WebSecurityConfigurerAdapter

WebSecurityConfigurerAdapter

我正在使用OAuth2进行授权,但在WebSecurityConfigurerAdapter中找不到configure(HttpSecurity http)替代的用法,因为它根本没有执行,因为ResourceServerConfigurerAdapter优先于它。

执行顺序为:AuthorizationServerConfigurerAdapter-> ResourceServerConfigurerAdapter-> WebSecurityConfigurerAdapter。可以通过@Order手动更改它,但是它会以某种方式破坏令牌,因此我不希望这样做。

假设我评论了ResourceServerConfigurerAdapter中的所有内容,然后尝试访问/api/topics。在这种情况下,我将收到以下消息:

{
    "error": "unauthorized",
    "error_description": "Full authentication is required to access this resource"
}


这意味着即使在我拥有.antMatchers("/api/topics/**").permitAll()的情况下,我在WebSecurityConfigurerAdapter中拥有的规则也不会被执行。重点是什么?允许/api/**并授权其他任何内容的正确方法是什么?

顺便说一句,我正在使用[email protected]

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("userDetailsService")
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/topics/**").permitAll()
                .antMatchers("/api/users/**").permitAll()
                .antMatchers("/oauth/token**", "/oauth/authorize**").permitAll()
                .anyRequest().authenticated()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

}


@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

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

}


@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Value("${oauth.clientId}")
    private String clientId;

    @Value("${oauth.clientSecret}")
    private String clientSecret;

    @Value("${oauth.accessTokenValidity}")
    private int accessTokenValidity;

    @Value("${oauth.refreshTokenValidity}")
    private int refreshTokenValidity;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    @Qualifier("userDetailsService")
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
                .inMemory()
                .withClient(clientId)
                .secret(bCryptPasswordEncoder.encode(clientSecret))
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .autoApprove(true)
                .scopes("read", "write", "trust")
                .accessTokenValiditySeconds(accessTokenValidity)
                .refreshTokenValiditySeconds(refreshTokenValidity);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .tokenStore(tokenStore)
                .userDetailsService(userDetailsService)
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer auth) throws Exception {
        auth
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

}

最佳答案

由于通过AuthorizationServer和ResourceServer的配置重新注册了许多SecurityFilterChain(Interceptors),因此失去了WebSecurityConfigurerAdapter的执行优先级,以确保一切正常运行,因此必须在SecurityConfig上进行设置:

    @Order(1)
    @Override
    protected void configure(HttpSecurity http) throws Exception {
          //... custom code
    }


在ResourceServerConfiguration中,写http.requestMatchers().antMatchers而不是仅仅写http.authorizeRequests().antMatchers是非常重要的,因为这允许筛选器可以彼此正常工作,相对于端点“ / api / **”而言,ResourceServerConfiguration的优先级高于SecurityConf。

    private static final String ANT_MATCHER_API = "/api/**";

    @Order(2)
    @Override
    protected void configure(HttpSecurity http) throws Exception {
           http
                .requestMatchers()
                .antMatchers(ANT_MATCHER_API).and()
                .authorizeRequests().antMatchers(ANT_MATCHER_API).access("#oauth2.hasScope('read')").and()
                .authorizeRequests().antMatchers(ANT_MATCHER_API).access("#oauth2.hasScope('write')")
                .and()
                .exceptionHandling()
        //... custom code
    }


顺便说一句错误:
{
    “错误”:“未经授权”,
    “ error_description”:“访问此资源需要完全认证”
}

是Oauth2过滤器链的错误

关于java - OAuth2 WebSecurityConfigurerAdapter规则的重点是什么,因为它比ResourceServerConfigurerAdapter没有优先级,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61154266/

10-10 14:42