web-dev-qa-db-fra.com

Spring Security OAuth2, qui décide de la sécurité?

J'ai essayé d'implémenter un serveur d'authentification OAuth2 en utilisant les guides de Dave Syer avec une certaine inspiration de JHipster. Mais je ne peux pas comprendre comment tout cela fonctionne ensemble.

Il semble que la configuration de sécurité à l'aide de WebSecurityConfigurerAdapter soit écrasée lorsque j'utilise ResourceServerConfigurerAdapter.

@Configuration
@EnableResourceServer
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {

    private TokenExtractor tokenExtractor = new BearerTokenExtractor();

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .addFilterAfter(contextClearer(), AbstractPreAuthenticatedProcessingFilter.class)
                .authorizeRequests()
                .anyRequest().authenticated().and().httpBasic();
    }

    private OncePerRequestFilter contextClearer() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
                if (tokenExtractor.extract(request) == null) {
                    SecurityContextHolder.clearContext();
                }
                filterChain.doFilter(request, response);
            }
        };
    }

@Component
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    private final AuthenticationManager authenticationManager;

    @Autowired
    public CustomWebSecurityConfigurerAdapter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .parentAuthenticationManager(authenticationManager);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .formLogin()
                    .loginPage("/login").permitAll()
                .and()
                    .authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .and()
                    .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and()
                    .authorizeRequests().anyRequest().authenticated();
    }
}

C'est du code tiré de quelques exemples différents, donc ils pourraient ne pas bien se mélanger. Mais je ne trouve pas une bonne liste de documentation/d'exemples pour OAuth2 (contrairement à Spring Boot qui a une documentation impressionnante), j'ai donc des problèmes pour comprendre comment tous ces éléments s'emboîtent. Si je n'ajoute pas le loginForm au ResourceServerConfigurerAdapter, il me donnera simplement non autorisé. Mais je l'ai défini dans WebSecurityConfigurererAdapter comme permitAll ().

Il s'agit de AuthorizationServerConfigurerAdapter:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("acme")
                .secret("acmesecret")
                .authorizedGrantTypes("authorization_code", "refresh_token",
                        "password").scopes("openid");
    }

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

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

Quelque chose que je fais mal? Dois-je configurer toute la sécurité dans le ResourceServerConfigurerAdapter? Ai-je même encore besoin de WebSecurityConfigurerAdapter?

Si quelqu'un connaît des guides, des tutoriels, des blogs ou tout ce qui pourrait m'aider à comprendre comment cela fonctionne, ce serait grandement apprécié.

Cordialement, Kenneth.

33
LG87

Vous avez besoin d'un WebSecurityConfigurerAdapter pour sécuriser le point de terminaison/authorize et pour permettre aux utilisateurs de s'authentifier. Une application Spring Boot ferait cela pour vous (en ajoutant son propre WebSecurityConfigurerAdapter avec l'authentification de base HTTP). Il crée une chaîne de filtres avec order = 0 par défaut et protège toutes les ressources sauf si vous fournissez un filtreur de demandes. Le @EnableResourceServer fait quelque chose de similaire, mais la chaîne de filtres qu'il ajoute est à l'ordre = 3 par défaut. WebSecurityConfigurerAdapter a une annotation @Order (100). Ainsi, le ResourceServer sera d'abord vérifié (authentification), puis vos vérifications dans votre extension de WebSecurityConfigureAdapter seront vérifiées.

Votre configuration semble saine d'esprit (la chaîne de connexion est prioritaire, mais ne correspond qu'à un petit ensemble de demandes).

39
Dave Syer