1

Actuellement, je fais l'expérience de la nouvelle pile réactive Spring, et je veux utiliser des fonctionnalités réactives dans Spring Session 2.0.Comment utiliser Spring WebSessionIdResolver avec Spring Security 5 dans une application Webflux Spring?

Dans l'approche Servlet traditionnelle, Spring Session fournit un HttpSessionStrategy pour détecter la session dans les en-têtes de cookie ou de requête. Il est facile d'utiliser HeaderHttpSessionStrategy pour implémenter une authentification de type jeton (par défaut, le nom est X-AUTH-TOKEN) pour les API RESTful. Le ressort 5 core fournit un WebSessionIdResolver pour faire la même chose pour l'environnement réactif. Mais quand je l'utilise avec Spring Security et que je souhaite que cela fonctionne comme d'habitude, je n'arrive pas à le faire fonctionner.

Le fichier SessionConfig.

@EnableSpringWebSession 
public class SessionConfig { 

    @Bean 
    public ReactorSessionRepository sessionRepository() { 
     return new MapReactorSessionRepository(new ConcurrentHashMap<>()); 
    } 

    @Bean 
    public WebSessionIdResolver headerWebSessionIdResolver() { 
     HeaderWebSessionIdResolver resolver = new HeaderWebSessionIdResolver(); 
     resolver.setHeaderName("X-SESSION-ID"); 
     return resolver; 
    } 
} 

Le SecurityConfig partiel.

@EnableWebFluxSecurity 
class SecurityConfig { 

    @Bean 
    SecurityWebFilterChain springWebFilterChain(HttpSecurity http) throws Exception { 
     return http 
      .authorizeExchange() 
      .pathMatchers(HttpMethod.GET, "/posts/**").permitAll() 
      .pathMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN") 
      //.pathMatchers("https://stackoverflow.com/users/{user}/**").access(this::currentUserMatchesPath) 
      .anyExchange().authenticated() 
      .and() 
      .build(); 
} 

Un fichier de contrôleur de repos de test, il renvoie l'ID de session en cours.

@RestController 
public class SessionRestController { 


    @GetMapping("/sessionId") 
    public Map<String, String> sessionId(WebSession session){ 
     Map<String, String> map = new HashMap<>(); 
     map.put("id", session.getId()); 
     return map ; 
    } 

} 

Quand j'ai commencé l'application et utiliser curl pour accéder au/sessionId, il n'y a pas d'information de session, l'en-tête de réponse.

curl -v -u "user:password" http://localhost:8080/sessionId 

Et je suis l'identifiant de session dans le résultat de la requête et le mettre en-têtes de requête pour accéder aux ressources protégées et a obtenu 401.

curl -v -X POST -H "X-SESSION-ID:xxxx" http://localhost:8080/posts 

Mise à jour: Un échantillon de travail peut être trouvé here .

Répondre

0

Le module spring-web de Spring Framework utilise par défaut CookieWebSessionIdResolver, qui est basé sur des cookies. Si vous créez un bean alternatif de type HeaderWebSessionIdResolver, il sera automatiquement récupéré par Spring Session et passera à une stratégie basée sur l'en-tête.

Dans l'une ou l'autre stratégie, il est conçu pour lire les en-têtes ServerExchange entrants et rechercher l'ID de session, qu'il s'agisse de lire l'en-tête Cookie ou l'en-tête SESSION. Ces stratégies créent également des en-têtes de réponse, qu'il s'agisse d'une directive set-cookie pour le client (navigateur Web ou votre code) pour remplir le cookie ou pour vous donner l'en-tête SESSION (nom par défaut du nom d'en-tête HeaderWebSessionIdResolver) .

+0

Je le sais clairement, et j'ai lu les codes de test de 'WebSessionIdResolver'. Mais cela ne fonctionne pas comme prévu lorsqu'il est utilisé avec Spring Session et Spring Security dans mon exemple. J'ai utilisé 'curl' pour tester mes APIs, l'information de session n'a pas été ajoutée dans l'en-tête de réponse, et je ne vérifie pas non plus la session que j'ai reçue de la première requête dans les étapes suivantes. – Hantsy

+0

Mis à jour mes codes pour Spring Boot 2.0.0.M6 et le faire fonctionner, vérifiez les [exemples de codes] (https://github.com/hantsy/spring-reactive-sample/tree/master/session-header). – Hantsy