OAuth2 - @EnableResourceServer vs @ EnableOAuth2Sso

OAuth2 - @EnableResourceServer vs @ EnableOAuth2Sso

1. Vue d'ensemble

Dans ce didacticiel, nous allons parler des annotations@EnableResourceServer et@EnableOAuth2Sso dans Spring Security.

Nous allons commencer par expliquer lesdifferences between an OAuth2 Client and an OAuth2 Resource Server. Ensuite, nous parlerons un peu de ce que ces annotations peuvent faire pour nous et démontrerons leur utilisation avec un exemple utilisantZuul et une API simple.

Pour les besoins de cet article, nous allons supposer une expérience préexistante avecZuul etOAuth2.

Si vous n'en avez pas ou pensez qu'un examen de l'un ou l'autre serait utile, veuillez consulter nosquick overview on Zuul et nosguide to OAuth2.

2. OAuth2 Client et serveur de ressources

Il existe quatreroles différents dans OAuth2 que nous devons prendre en compte:

  • Resource Owner - une entité capable d'accorder l'accès à ses ressources protégées

  • Authorization Server - accorde des jetons d'accès àClients après avoir authentifié avec succèsResourceOwners et obtenu leur autorisation

  • Resource Server - un composant qui nécessite un jeton d'accès pour autoriser, ou au moins envisager, l'accès à ses ressources

  • Client - une entité capable d'obtenir des jetons d'accès auprès des serveurs d'autorisation

L'annotation de notre classe de configuration avec@EnableResourceServer ou@EnableOAuth2Sso indique à Spring de configurer les composants qui transforment notre application en l'un des deux derniers rôles mentionnés ci-dessus.

The @EnableResourceServer annotation enables our application to behave as a Resource Server en configurant unOAuth2AuthenticationProcessingFilter et d'autres composants tout aussi importants.

Consultez la classeResourceServerSecurityConfigurer pour avoir une meilleure idée de ce qui est configuré dans les coulisses.

Inversement,the @EnableOAuth2Sso annotation transforms our application into an OAuth2 client. Il demande à Spring de configurer unOAuth2ClientAuthenticationProcessingFilter, ainsi que d'autres composants dont notre application a besoin pour être capable d'obtenir des jetons d'accès d'un serveur d'autorisation.

Jetez un œil à la classeSsoSecurityConfigurer pour plus de détails sur ce que Spring configure pour nous.

La combinaison de ces annotations avec certaines propriétés nous permet d’activer rapidement les choses. Créons deux applications différentes pour les voir en action et comment elles peuvent se compléter:

  • Notre première application sera notre nœud de périphérie, une simple applicationZuul qui utilisera l'annotation@EnableOAuth2Sso. Il sera chargé d’authentifier les utilisateurs (à l’aide d’unAuthorizationServer) et de déléguer les demandes entrantes à d’autres applications

  • La deuxième application utilisera l'annotation@EnableResourceServer et autorisera l'accès aux ressources protégées si les demandes entrantes contiennent un jeton d'accès OAuth2 valide

3. Zuul -@EnableOAuth2Sso

Commençons par créer une applicationZuul qui agira comme notre nœud périphérique et qui sera responsable de l'authentification des utilisateurs à l'aide d'un OAuth2AuthorizationServer:

@Configuration
@EnableZuulProxy
@EnableOAuth2Sso
@Order(value = 0)
public class AppConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private ResourceServerTokenServices
      resourceServerTokenServices;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authorization-server-1/**",
              "/login").permitAll()
            .anyRequest().authenticated().and()
            .logout().permitAll().logoutSuccessUrl("/");
    }
}

Annoter notre applicationZuul avec@EnableOAuth2Sso avertit également Spring de configurer un filtreOAuth2TokenRelayFilter. Ce filtre récupère les jetons d'accès obtenus précédemment à partir des sessions HTTP des utilisateurs et les propage en aval.

Notez que nous utilisons également l'annotation@Order dans notre classe de configurationAppConfiguration. Ceci permet de s'assurer que lesFilters créés par nosWebSecurityConfigurerAdapter ont priorité sur lesFilters créés par les autresWebSecurityConfigurerAdapters.

Par exemple, nous pourrions annoter notre applicationZuul avec@EnableResourceServer pour prendre en charge les identificateurs de session HTTP et les jetons d'accès OAuth2. Cependant, cela crée de nouveauxFilters qui, par défaut, ont priorité sur ceux créés par la classeAppConfiguration. Cela se produit carResouceServerConfiguration, une classe de configuration déclenchée par@EnableResourceServer, spécifie unorder par défaut de 3 tandis queWebSecurityConfigureAdapter a unorder par défaut de 100.

Avant de passer à nosResourceServer,, nous devons configurer certaines propriétés:

zuul:
  routes:
    resource-server-mvc-1: /resource-server-mvc-1/**
    authorization-server-1:
      sensitiveHeaders: Authorization
      path: /authorization-server-1/**
      stripPrefix: false
  add-proxy-headers: true

security:
  basic:
    enabled: false
  oauth2:
    sso:
      loginPath: /login
    client:
      accessTokenUri: http://localhost:8769/authorization-server-1/oauth/token
      userAuthorizationUri: /authorization-server-1/oauth/authorize
      clientId: fooClient
      clientSecret: fooSecret
    resource:
      jwt:
        keyValue: "abc"
      id: fooScope
      serviceId: ${PREFIX:}resource

Sans entrer trop dans les détails, en utilisant cette configuration, nous sommes:

  • Configurer nos routesZuulet dire quels en-têtes doivent être ajoutés / supprimés avant d'envoyer des requêtes en aval.

  • Définition de certaines propriétés OAuth2 pour que notre application puisse communiquer avec nosAuthorizationServer et configuration deJWT avec le cryptagesymmetric.

4. API -@EnableResourceServer

Maintenant que nous avons notre applicationZuul en place, créons nosResourceServer:

@SpringBootApplication
@EnableResourceServer
@Controller
@RequestMapping("/")
class ResourceServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ResourceServerApplication.class, args);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String helloWorld(Principal principal) {
        return "Hello " + principal.getName();
    }
}

Il s’agit d’une application simple qui expose un seul point de terminaison pour renvoyer lesname desPrincipal qui ont initié la demande.

Terminons en configurant certaines propriétés:

security:
  basic:
    enabled: false
  oauth2:
    resource:
      jwt:
        keyValue: "abc"
      id: fooScope
      service-id: ${PREFIX:}resource

Gardez à l'esprit quewe need a valid access token (qui est stocké dans la session HTTP de l'utilisateur dans notre nœud périphérique)to access the endpoint of our Resource Server.

5. Conclusion

Dans cet article, nous avons expliqué les différences entre les annotations@EnableOAuth2Sso et@EnableResourceServer. Nous avons également montré comment les utiliser avec un exemple pratique utilisantZuul et une API simple.

L'implémentation complète de cet exemple peut être trouvéeover on Github.

Lors de l'exécution locale, nous pouvons exécuter et tester l'application àhttp://192.168.1.67:8765/resource-server-mvc-1