OAuth2 Какой смысл правил WebSecurityConfigurerAdapter, поскольку он не имеет приоритета над ResourceServerConfigurerAdapter - PullRequest
0 голосов
/ 11 апреля 2020

Я использую OAuth2 для авторизации и не нахожу использование переопределения configure(HttpSecurity http) в WebSecurityConfigurerAdapter, так как он вообще не выполняется, потому что ResourceServerConfigurerAdapter имеет приоритет над ним.

Порядок выполнения Это: AuthorizationServerConfigurerAdapter -> ResourceServerConfigurerAdapter -> WebSecurityConfigurerAdapter. Он может быть вручную изменен на @Order, но он каким-то образом нарушает токены, поэтому я бы предпочел этого не делать.

Допустим, я комментирую все в ResourceServerConfigurerAdapter и затем пытаюсь получить доступ к /api/topics. В этом случае я получу следующее сообщение:

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

Это означает, что правила, которые у меня есть в WebSecurityConfigurerAdapter, вообще не выполняются, даже если у меня .antMatchers("/api/topics/**").permitAll(). В чем смысл? Как правильно разрешить /api/** и разрешить что-нибудь еще?

Кстати, я использую spring-security-oauth2-autoconfigure@2.2.6.RELEASE.

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

}

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Поскольку вы регистрируете много SecurityFilterChain (Interceptors) с помощью конфигурации AuthorizationServer и ResourceServer, приоритет выполнения, который имел WebSecurityConfigurerAdapter, был потерян, чтобы добиться того, чтобы все работало правильно, вы должны установить его в SecurityConfig:

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

В ResourceServerConfiguration очень важно писать http.requestMatchers().antMatchers, а не просто http.authorizeRequests().antMatchers, поскольку это позволяет фильтрам работать правильно друг с другом, имея приоритет ResourceServerConfiguration над SecurityConf относительно конечных точек "/ api / **"

    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": "unauthorized", "error_description": "Для доступа к этому ресурсу требуется полная аутентификация"}

- ошибка цепочки фильтров Oauth2

1 голос
/ 11 апреля 2020

Я нашел ответ сам. WebSecurityConfigurerAdapter.configure должен иметь конфигурацию для аутентификации, такую ​​как страница входа, страница ошибки и т. Д. c. Что касается ResourceServerConfigurerAdapter.configure, он применяет правила к API REST.

Причина, по которой WebSecurityConfigurerAdapter у меня не работает, заключается в том, что конфигурации WebSecurityConfigurerAdapter и ResourceServerConfigurerAdapter связаны между собой. Помните их заказ? Сервер аутентификации -> Сервер ресурсов -> Веб-безопасность. В моем случае у меня был .anyRequest().authenticated() в ResourceServerConfigurerAdapter.configure, который в основном аутентифицировал все запросы после этого, поэтому он вообще не мог достичь WebSecurityConfigurerAdapter.

Я также добавил .antMatcher("/api/users**") в ResourceServerConfigurerAdapter.configure, чтобы ограничить это правило только /api/users.

Вот "неработающий код":

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

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

Здесь рабочий пример:

// WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/oauth2/keys").permitAll()
            .anyRequest().authenticated();
}

// ResourceServerConfigurerAdapter
@Override
public void configure(HttpSecurity http) throws Exception {
    http
            .antMatcher("/api/users**") // that particular line applies the rule only for /api/users
            .authorizeRequests()
            .antMatchers("/api/users**").permitAll();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...