1.配置SecurityConfiguration

/**
 * login 模块的 Security 配置
 */
@Configuration("authSecurityConfiguration")
@Slf4j
public class SecurityConfiguration {

    @Resource
    private CustomOAuth2SuccessHandler customOAuth2SuccessHandler;

    @Bean("authAuthorizeRequestsCustomizer")
    public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
        return new AuthorizeRequestsCustomizer() {
            @Override
            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
                try {
                    registry.antMatchers("/oauth2/authorization/google","/oauth2/callback/google","/favicon.ico").permitAll()
                            .and()
                            .oauth2Login()
                            .authorizationEndpoint()
                            .baseUri("/oauth2/authorization")
                            .and()
                            .redirectionEndpoint()
                            .baseUri("/auth2/callback/google")
                            .and()
                            .successHandler(customOAuth2SuccessHandler);
                } catch (Exception e) {
                    log.error("cn.module.member.framework.security.config.SecurityConfiguration msg:{}",e.getMessage(), e);
                }
            }
        };
    }
}
  • 我这个是配置了一个WebSecurityConfigurerAdapter 里面会通过 它循环获取自定义的配置,如果只有一个配置而非多个的话,需要继承Security的Configuration

.authorizeRequests(registry -> authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))

  • 创建一个身份验证成功的处理器

@Component
@Slf4j
public class CustomOAuth2SuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
        OAuth2User oauthUser = oauthToken.getPrincipal();  // 获取 OAuth2 用户信息

        // 从 Google 返回的 OAuth2User 中提取用户信息
        String email = oauthUser.getAttribute("email");
        String name = oauthUser.getAttribute("name");
        log.info("cn.module.member.framework.security.core.CustomOAuth2SuccessHandler.onAuthenticationSuccess email:{},name:{}",email,name);
        // todo 处理后续逻辑
    }
}

2.引用相关依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>

3.配置yaml 文件

spring:
  # google登录
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: "client-id" # 从Google开发者平台获取
            client-secret: "client-secret" #从Google开发者平台获取
            scope:
              - profile
              - email
            redirect-uri: "{baseUrl}/transmit/oauth2/authorization/google"
        provider:
          google:
            authorization-uri: https://accounts.google.com/o/oauth2/v2/auth
            token-uri: https://oauth2.googleapis.com/token
            user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo

Tip:

在google登录成功的时候遇到了一次无限循环递归的问题,问题出现自在通过google去校验登录信息的时候.连接超时了。开启代理之后问题解决

  • 递归的方法是

d
  • 错误日志

java.lang.StackOverflowError: null
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:234)
	at com.sun.proxy.$Proxy701.authenticate(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:234)
	at com.sun.proxy.$Proxy701.authenticate(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:234)
	at com.sun.proxy.$Proxy701.authenticate(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
  • 原因

    • 当走到result = provider.authenticate(authentication); 方法时,会去向google验证当前的用户信息,因为没开vpn所以会抛出连接超时异常,然后会一直循环的走入这个方法,导致之后出现 堆栈溢出

org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: I/O error on POST request for "https://oauth2.googleapis.com/token": Connection timed out: connect; nested exception is java.net.ConnectException: Connection timed out: connect