【问题标题】:Can't access OAuth2AuthenticationToken when using Google OAuth2 in Spring Boot在 Spring Boot 中使用 Google OAuth2 时无法访问 OAuth2AuthenticationToken
【发布时间】:2020-02-16 16:35:50
【问题描述】:

我正在尝试使用自定义 defaultSuccessUrl 将使用 google 登录到我的 Spring Boot 应用程序中。身份验证似乎通过了,但是当我到达成功 url 端点时,我无法获得 OAuth2AuthenticationToken (如果将其作为方法的参数,则它为空)并且当我从安全上下文中获取身份验证时,它返回为 AnonymousAuthenticationToken因此:

我添加了这些依赖项:

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

这是我的安全配置:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .mvcMatchers("/api/users/login").permitAll()
                .requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated()
                .antMatchers("/api/users/login**","/callback/", "/webjars/**", "/error**").permitAll()
                .antMatchers("/oauth_login", "/loginFailure", "/").permitAll()
                .anyRequest().authenticated()
                .and()
                .oauth2Login()
                .defaultSuccessUrl("/api/users/loginSuccess", true)
                .failureUrl("/loginFailure");

        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

这里是成功的终点:


@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {

    private final OAuth2AuthorizedClientService authorizedClientService;


    @GetMapping("/loginSuccess")
    public String getLoginInfo(Model model, OAuth2AuthenticationToken authentication) {
        OAuth2AuthorizedClient client = authorizedClientService
                .loadAuthorizedClient(authentication.getAuthorizedClientRegistrationId(), authentication.getName());

        String userInfoEndpointUri = client.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri();

        if (!StringUtils.isEmpty(userInfoEndpointUri)) {
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + client.getAccessToken().getTokenValue());
            HttpEntity entity = new HttpEntity("", headers);

            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<Map> response = restTemplate.exchange(userInfoEndpointUri, HttpMethod.GET, entity, Map.class);
            Map userAttributes = response.getBody();

            model.addAttribute("name", userAttributes.get("name"));
        }


        return "loginSuccess";
    }

}

它正确地重定向到端点,但OAuth2AuthenticationToken 为空,正如我之前所说的安全上下文中的身份验证是匿名身份验证。没有提供正确的 Authentication 对象的问题在哪里?

【问题讨论】:

    标签: java spring spring-boot oauth-2.0 google-oauth


    【解决方案1】:

    我有同样的问题,我的解决方案不是 100% 完美,但它确实有效。你可以删除

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    

    使用SessionCreationPolicy.STATELESS 成功登录后,您只会以匿名身份(ROLE_ANONYMOUS)转发到您的defaultSuccessUrl

    o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@41c9a549
    s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
    .....
    o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@1c19acdf: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@43458: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: ......................; Granted Authorities: ROLE_ANONYMOUS'
    

    但如果您删除 STATELESS,那么您的对象将设置为 OAuth2AuthenticationToken authentication,并且在日志中,您将看到 ROLE_USER 的不同输出

    o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@274a9530
    w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@ffb235ff: Authentication: org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken@ffb235ff: Principal: Name: [111026035798596971137], Granted Authorities: [[ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=lRLZ7qJohqoHD5EiCjufeA, sub=111026035798596971137, email_verified=true, iss=https://accounts.google.com, given_name=Andrzej, locale=pl, nonce=-................-W3M, picture=https://lh5.googleusercontent.com/-5vFrrro_VtI/AAAAAAAAAAI/AAAAAAAAAAA/...........-_A/s96-c/photo.jpg, aud=[.........-................apps.googleusercontent.com], azp=...-...........apps.googleusercontent.com, name=Andrzej ..., hd=.....pl, exp=2020-04-27T14:54:48Z, family_name=......, iat=2020-04-27T13:54:48Z, email=a.....@.....pl}]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: ...............; Granted Authorities: ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid' stored to HttpSession: 'org.apache.catalina.session.StandardSessionFacade@7bfa86bb
    s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
    .....
    o.s.s.w.a.AnonymousAuthenticationFilter  : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken@ffb235ff: Principal: Name: [............], Granted Authorities: [[ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=........., sub=............, email_verified=true, iss=https://accounts.google.com, given_name=Andrzej, locale=pl, nonce=-...............-W3M, picture=https://lh5.googleusercontent.com/-5vFrrro_VtI/..........-_A/s96-c/photo.jpg, aud=[.....-............apps.googleusercontent.com], azp=224074472498-................apps.googleusercontent.com, name=Andrzej ....., hd=....pl, exp=2020-04-27T14:54:48Z, family_name=.............., iat=2020-04-27T13:54:48Z, email=a..........@.....pl}]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: ...........; Granted Authorities: ROLE_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid'
    

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 1970-01-01
      • 2018-02-05
      • 2018-03-29
      • 1970-01-01
      • 2017-04-25
      • 2018-12-01
      • 2018-05-03
      • 1970-01-01
      相关资源
      最近更新 更多