【问题标题】:Issues while implementing the authorization code grant in spring春季实施授权码授予时的问题
【发布时间】:2018-08-12 04:38:54
【问题描述】:

到目前为止,我已经使用了密码授权类型,并且效果很好。 最近我开始在我的项目中实现 OAuth 的授权码授予。我能够从服务器获取授权码。使用代码我再次能够获得访问令牌。

问题是我无法使用我的访问令牌访问资源服务器。每次尝试访问任何资源时,我都会被重定向到 Spring 的默认 /login 页面。

以下是资源服务器

@Configuration
@PropertySource("classpath:webservices-application.properties")
@EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter{

    @Value("${security.oauth2.resource.id}")
    private String resourceId;

    @Bean
    public JdbcTokenStore getTokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Autowired
    private DataSource dataSource;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/oauth/**","/login","/").permitAll()
                .anyRequest().authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(getTokenStore())
                .resourceId(resourceId).stateless(false);
    } 
} 

网络安全:

@Configuration
@EnableWebSecurity
@EnableOAuth2Sso
public class CustomWebsecurity extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/oauth/**","/login","/").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin();
    }
} 

授权服务器:

@Configuration
@EnableAuthorizationServer
@EnableOAuth2Sso
protected class AuthorizationApplication extends AuthorizationServerConfigurerAdapter {

    @Autowired
    public AuthorizationApplication (ApplicationContext applicationContext, AuthenticationManager authenticationManager) {
        this.passwordEncoder = applicationContext.getBean(PasswordEncoderImpl.class);
        this.authenticationManager = authenticationManager;
    }

    private PasswordEncoder passwordEncoder;

    private AuthenticationManager authenticationManager;

    @Bean
    protected AuthorizationCodeServices getAuthorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(dataSource);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        AuthorizationCodeServices services = getAuthorizationCodeServices();
        JdbcTokenStore tokenStore = getTokenStore();
        endpoints
                .userDetailsService(userDetailsService)
                .authorizationCodeServices(services)
                .authenticationManager(authenticationManager)
                .tokenStore(tokenStore)
                .approvalStoreDisabled();
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients();
        security.passwordEncoder(passwordEncoder);
    }
}

问题可能是由于 WebSecurity 类的某些配置不正确。但是,我尝试了多种配置,但都没有成功。

【问题讨论】:

  • 为什么你在AuthorizationServerConfigurerAdapter 中使用approvalStoreDisabled() ??
  • 我现在不需要实现细化权限,所以禁用它。但这应该不是问题,对吧?
  • 我认为授权服务器无法验证您的访问令牌。这可能是一个帮助stackoverflow.com/questions/29596036/…
  • 我检查了另一个问题。我的问题有点不同。我的ResourceServerAuthorizationServer 获得了相同的令牌引用,因为我能够通过密码授予类型访问资源。我的问题是即使使用正确的令牌也重定向到登录端点。这似乎更像是一个配置问题。这也很可能是由于我最近添加的 WebSecurityConfigurerAdapter 类。
  • 只是为了保护authorize 端点。我找不到添加EnableOAuth2Sso 的地方。每当我尝试访问资源时,使用 EnableOAuth2Sso 注释 AuthorizationServer 或 ResourceServer 或两者都会给我一个错误:HTTP URL must not be null。与此处报告的错误类似:github.com/spring-guides/tut-spring-boot-oauth2/issues/… 您是否知道为什么会发生此错误?删除 WebSecurity 类后,我已经在 ResourceServer 的配置方法中添加了formLogin()

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


【解决方案1】:

在@dur 的一些指导下,我能够找到解决方案。 Here's one of the culprits:

OAuth2 资源过滤器的默认顺序已从 3 更改为 SecurityProperties.ACCESS_OVERRIDE_ORDER - 1。这将其放置在执行器端点之后,但在基本身份验证过滤器链之前。可以通过设置 security.oauth2.resource.filter-order = 3 恢复默认值

总而言之,我做了以下改动:

  1. ResourceServerAuthorizationServer 使用@EnableOauth2Client 而不是@EnableOAuth2Sso,因为后者给了我以下错误:

    java.lang.IllegalArgumentException: URI must not be null
    
  2. 删除CustomWebSecurity 并在ResourceServer 本身中进行所有安全配置。

  3. 通过将以下内容放入属性文件中来更改资源过滤器的过滤顺序:

    security.oauth2.resource.filter-order = 3
    
  4. 安全配置中的一些基本更改。


这是我现在的ResourceServer 课程:

@Configuration
@PropertySource("classpath:webservices-application.properties")
@EnableResourceServer
@EnableOAuth2Sso
public class ResourceServer extends ResourceServerConfigurerAdapter{

    @Value("${security.oauth2.resource.id}")
    private String resourceId;

    @Bean
    public JdbcTokenStore getTokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Autowired
    private DataSource dataSource;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .requestMatchers().antMatchers(
                "/protected_uri_1",
                "/protected_uri_2",
                "/protected_uri_3")
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
        .and().formLogin();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(getTokenStore())
                .resourceId(resourceId);
    }

}

【讨论】:

  • 您是否有完整的项目示例可以放在 GitHub 上?我从头开始,您的配置仍然无法正常工作。身份验证端点通过密码或授权码授予获取 access_token,但保护 API 端点根本不起作用:(
猜你喜欢
  • 1970-01-01
  • 2011-05-15
  • 2020-05-05
  • 2014-04-07
  • 2018-01-12
  • 2017-08-27
  • 1970-01-01
  • 2018-06-29
  • 2018-10-25
相关资源
最近更新 更多