Spring Boot 2 + OAuth2:为 Token 配置 Auth Code 交换

Posted

技术标签:

【中文标题】Spring Boot 2 + OAuth2:为 Token 配置 Auth Code 交换【英文标题】:Spring Boot 2 + OAuth2: Configure Exchange of Auth Code for Token 【发布时间】:2018-08-25 02:16:56 【问题描述】:

我已经按照Spring Boot OAuth2 教程来配置 OAuth2 客户端。不幸的是,一旦“用户”通过 Idp (Okta) 进行身份验证,就会发生带有“代码”的重定向,从而导致重定向循环:/login -> /authorize... -> /login... -> /login

Firefox 检测到服务器正在以永远不会完成的方式重定向对该地址的请求。

有谁知道问题是什么或可能是什么以及如何解决?详情如下。

Okta 配置:

登录重定向 URI:http://localhost:8080/auth/login

注销重定向 URI: http://localhost:8080/auth/logout

登录发起者:仅限应用

发起登录 URI:http://localhost:8080/auth/login

配置属性为:

okta:
  oauth2:
    client:
      client-id: clientId
      client-secret: clientSecret
      scope: openid profile email
      client-authentication-scheme: form
      access-token-uri: https://mydomain.oktapreview.com/oauth2/myapp/v1/token
      user-authorization-uri: https://mydomain.oktapreview.com/oauth2/myapp/v1/authorize
    resource:
      user-info-uri: https://mydomain.oktapreview.com/oauth2/myapp/v1/userinfo

过滤器是:

  private Filter filter() 
    OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(
        "/login");
    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(oktaClient(), oauth2ClientContext);
    filter.setRestTemplate(restTemplate);
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(oktaResource().getUserInfoUri(),
        oktaClient().getClientId());
    tokenServices.setRestTemplate(restTemplate);
    filter.setTokenServices(tokenServices);

    return filter;
  

WebSecurityConfigurerAdapter 配置为:

  @Configuration
  @EnableOAuth2Client
  public class WebSecConfig extends WebSecurityConfigurerAdapter 
  ....
  @Override
  public void configure(HttpSecurity http) throws Exception 
    http.antMatcher("/**").authorizeRequests()
        .antMatchers("/", "/login**", "/logout**", "/v2/api-docs", "/configuration/ui",
            "/configuration/security", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**")
        .permitAll()
        .anyRequest().authenticated().and().exceptionHandling()
        .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")).and().csrf()
        .csrfTokenRepository(
            CookieCsrfTokenRepository.withHttpOnlyFalse()).and().addFilterBefore(filter(),
        BasicAuthenticationFilter.class);
  
  ....
  

更新: 解决方案是将LoginUrlAuthenticationEntryPoint("/login") 更改为LoginUrlAuthenticationEntryPoint("/") 并重新创建授权服务器。

【问题讨论】:

请用主课更新您的问题 【参考方案1】:

您应该使用默认授权服务器,或者您创建的一个。如果您使用默认值,它应该类似于:

https://mydomain.oktapreview.com/oauth2/default

【讨论】:

我创建了一个新的身份验证服务器,现在问题是重定向循环。关于问题/解决方案的任何想法? 我建议使用 Okta 教程来解决您的问题。写了好几篇,希望能帮上忙。你的用例是什么?您是否只想使用 Spring Boot 2 / Spring Security 5 登录 Spring Boot 应用程序? 最终目标是让基于 Spring Boot 2 的 API(使用 Spring Security + OAuth2)对单页应用程序的用户进行身份验证/授权。在身份验证时,我想让 JWT 返回到 SPA。对于每个请求,我希望 API 验证 JWT 并通过 JWT 中包含的“组”声明验证授权。当 JWT 过期时,我希望通过刷新令牌刷新令牌。 我使用了您的tutorials 之一和simple Spring tutorial 来通过@EnableOAuth2Sso 进行身份验证。当我对根路径(即/)执行GET 请求时,我得到了所有完整的Principal 类内容,即使它是在Okta 的授权服务器中配置的,也需要刷新令牌。我还没有弄清楚如何通过 JWT 中包含的“组”声明验证 JWT 和验证授权或如何刷新。 Spring Security(和 Otka 的 Spring Boot 启动器)旨在为您处理提交刷新令牌以获得新的访问令牌。至于团体声称,您可以像我们在 JHipster 中那样做:github.com/mraible/jhipster-oidc-example/blob/master/src/main/…

以上是关于Spring Boot 2 + OAuth2:为 Token 配置 Auth Code 交换的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.0.0 + OAuth2

使用Spring boot的OAuth2认证服务器和资源服务器

Spring Boot OAuth2 自定义登录表单用例

Spring boot Basic Authentication和OAuth2在同一个项目中?

Spring Boot OAuth2:如何检索用户令牌信息详细信息

Spring Boot 2 和 OAuth2/JWT