在春季实施授权代码授权时出现的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在春季实施授权代码授权时出现的问题相关的知识,希望对你有一定的参考价值。

到目前为止,我已经有了密码授予类型,并且完美无缺。最近我开始在我的项目中实现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);
    } 
} 

WebSecurity:

@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();
    }
} 

AuthorizationServer:

@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类的某些配置不正确。但是,我尝试了多种配置而没有运气。

答案

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

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

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

  1. @EnableOauth2Client以及@EnableOAuth2Sso使用ResourceServer而不是AuthorizationServer,因为后者给了我以下错误: 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);
    }

}

以上是关于在春季实施授权代码授权时出现的问题的主要内容,如果未能解决你的问题,请参考以下文章

春季无法获取keycloak授权令牌

使用 Fabric SDK 从 Twitter 授权中取消时出现授权错误

如何在春季授权服务器中允许端点?

如何在春季启动中从未经授权的响应中删除变量

春季启动返回 401-未经授权,即使我允许它

如何在春季使用 OIDC 从授权服务器获取所有用户?