Une fois qu'un nouvel utilisateur a soumis un formulaire «Nouveau compte», je souhaite connecter manuellement cet utilisateur afin qu'il n'ait pas à se connecter sur la page suivante.
La page de connexion sous forme normale passant par l'intercepteur de sécurité Spring fonctionne très bien.
Dans le contrôleur de formulaire de nouveau compte, je crée un UsernamePasswordAuthenticationToken et le configure manuellement dans SecurityContext:
SecurityContextHolder.getContext().setAuthentication(authentication);
Sur cette même page, je vérifie plus tard que l'utilisateur est connecté avec:
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
Cela renvoie les autorités que j'ai définies plus tôt dans l'authentification. Tout est bien.
Mais lorsque ce même code est appelé sur la page suivante que je charge, le jeton d'authentification est simplement UserAnonymous.
Je ne sais pas pourquoi il n'a pas conservé l'authentification que j'ai définie sur la demande précédente. Des pensées?
- Cela pourrait-il être dû au fait que l'ID de session n'est pas configuré correctement?
- Y a-t-il quelque chose qui écrase peut-être mon authentification?
- Peut-être ai-je juste besoin d'une autre étape pour enregistrer l'authentification?
- Ou dois-je faire quelque chose pour déclarer l'authentification sur toute la session plutôt qu'une seule demande?
Je cherche juste quelques pensées qui pourraient m'aider à voir ce qui se passe ici.
la source
SecurityContextHolder.getContext().setAuthentication(authentication)
. Cela fonctionne et est courant, mais vous rencontrerez de graves lacunes de fonctionnalité si vous le faites simplement. Pour plus d'informations, voir ma question et la réponse: stackoverflow.com/questions/47233187/…Réponses:
J'ai eu le même problème que vous il y a quelque temps. Je ne me souviens pas des détails, mais le code suivant a fait fonctionner les choses pour moi. Ce code est utilisé dans un flux Spring Webflow, d'où les classes RequestContext et ExternalContext. Mais la partie la plus pertinente pour vous est la méthode doAutoLogin.
la source
@Configuration public class WebConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationProvider() throws Exception { return super.authenticationManagerBean(); } }
Je n'ai pas trouvé d'autres solutions complètes, alors j'ai pensé publier la mienne. Cela peut être un peu un hack, mais cela a résolu le problème au problème ci-dessus:
la source
authenticationManager
?Finalement compris la racine du problème.
Lorsque je crée le contexte de sécurité manuellement, aucun objet de session n'est créé. Ce n'est qu'à la fin du traitement de la demande que le mécanisme de sécurité Spring se rend compte que l'objet de session est nul (lorsqu'il essaie de stocker le contexte de sécurité dans la session après que la demande a été traitée).
À la fin de la demande, Spring Security crée un nouvel objet de session et un nouvel ID de session. Cependant, ce nouvel ID de session ne parvient jamais au navigateur car il se produit à la fin de la demande, après que la réponse au navigateur a été faite. Cela entraîne la perte du nouvel ID de session (et donc du contexte de sécurité contenant mon utilisateur connecté manuellement) lorsque la demande suivante contient l'ID de session précédent.
la source
Activez la journalisation du débogage pour obtenir une meilleure image de ce qui se passe.
Vous pouvez savoir si les cookies de session sont définis en utilisant un débogueur côté navigateur pour examiner les en-têtes renvoyés dans les réponses HTTP. (Il existe également d'autres moyens.)
Une possibilité est que SpringSecurity configure des cookies de session sécurisés, et votre prochaine page demandée a une URL "http" au lieu d'une URL "https". (Le navigateur n'enverra pas de cookie sécurisé pour une URL "http".)
la source
La nouvelle fonctionnalité de filtrage de Servlet 2.4 allège fondamentalement la restriction selon laquelle les filtres ne peuvent fonctionner que dans le flux de requêtes avant et après le traitement réel des requêtes par le serveur d'applications. Au lieu de cela, les filtres Servlet 2.4 peuvent désormais interagir avec le répartiteur de requêtes à chaque point de répartition. Cela signifie que lorsqu'une ressource Web transmet une requête à une autre ressource (par exemple, un servlet transmettant la requête à une page JSP dans la même application), un filtre peut fonctionner avant que la requête ne soit traitée par la ressource ciblée. Cela signifie également que si une ressource Web inclut la sortie ou la fonction d'autres ressources Web (par exemple, une page JSP comprenant la sortie de plusieurs autres pages JSP), les filtres Servlet 2.4 peuvent fonctionner avant et après chacune des ressources incluses. .
Pour activer cette fonctionnalité, vous devez:
web.xml
EnregistrementContrôleur
la source
J'essayais de tester une application extjs et après avoir défini avec succès un testingAuthenticationToken, cela a soudainement cessé de fonctionner sans cause évidente.
Je ne pouvais pas faire fonctionner les réponses ci-dessus, donc ma solution a été de sauter ce bout de printemps dans l'environnement de test. J'ai introduit une couture autour du ressort comme ceci:
L'utilisateur est un type personnalisé ici.
Je l'enveloppe ensuite dans une classe qui a juste une option pour que le code de test change de ressort.
La version de test ressemble à ceci:
Dans le code d'appel, j'utilise toujours un utilisateur approprié chargé à partir de la base de données:
Évidemment, cela ne conviendra pas si vous avez réellement besoin d'utiliser la sécurité, mais que je fonctionne avec une configuration sans sécurité pour le déploiement de test. Je pensais que quelqu'un d'autre pourrait se retrouver dans une situation similaire. C'est un modèle que j'ai déjà utilisé pour se moquer des dépendances statiques. L'autre alternative est que vous pouvez maintenir la statique de la classe wrapper mais je préfère celle-ci car les dépendances du code sont plus explicites car vous devez passer CurrentUserAccessor dans les classes où cela est nécessaire.
la source