Bonjour, je développe une application Web Java Spring Boot et je rencontre un problème lorsque l'utilisateur se connecte correctement l'application, l'application ramène l'utilisateur à la page de connexion pour une raison quelconque plutôt que de le ramener correctement à la page d'accueil. Cependant, une fois que l'utilisateur se connecte correctement la première fois (même s'il a été ramené à la page de connexion), il peut se déconnecter et s'il essaie de se reconnecter, il est correctement redirigé vers le "/ home "page. Je ne sais pas pourquoi cela ne se produit pas correctement du premier coup. Les différents morceaux de code qui ne fonctionnent pas correctement ensemble sont les suivants: 1. ma méthode configure (), que vous pouvez voir, devrait rediriger l'utilisateur vers "/ home" lors d'une connexion réussie. 2. les fonctions @RequestMapping dans mon AuthController. 3. mon fichier tiles.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd"> <tiles-definitions> <definition name="app.default" template="/WEB-INF/layouts/default.jsp"> <put-attribute name="title" value="bcore Hardware" /> </definition> <definition name="app.home" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/home.jsp" /> </definition> <!-- WILL NEED ITS OWN TEMPLATE --> <definition name="app.login" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/login.jsp" /> </definition> <!-- WILL NEED ITS OWN TEMPLATE --> <definition name="app.newRecord" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/newRecord.jsp" /> </definition> <definition name="app.viewRecord" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/viewRecord.jsp" /> </definition> <definition name="app.editRecord" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/editRecord.jsp" /> </definition> <definition name="app.account" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/account.jsp" /> </definition> <definition name="app.editAccount" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/editAccount.jsp" /> </definition> <definition name="app.register" extends="app.default"> <put-attribute name="content" value="/WEB-INF/tiles/register.jsp" /> </definition> </tiles-definitions>
@RequestMapping("/login") String admin() { return "app.login"; } @RequestMapping("/") String login() { return "app.login"; }
@Override protected void configure(HttpSecurity http) throws Exception { //@formatter:off http .authorizeRequests() .antMatchers( "/login", "/js/**", "/css/**", "/img/**").permitAll() .antMatchers("/register").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin().loginPage("/login") .defaultSuccessUrl("/home").permitAll() .and() .logout().permitAll(); }
Je veux qu'il soit structuré de sorte que l'utilisateur, sans être connecté, n'ait accéder à la page de connexion. Ensuite, après une connexion réussie, ils sont redirigés vers la page d'accueil avec différents privilèges à afficher en fonction des rôles, ce qui fonctionne correctement. Toute aide serait appréciée.
4 Réponses :
Je ne sais pas exactement ce qui cause le problème. Mais vous pouvez essayer d'éviter les lignes par défaut de login et successUrl et de les remplacer par .antMatchers (HttpMethod.POST, "/ login"). PermitAll ()
et en créant un contrôleur de Post / login. < pre> XXX
Je changerais l'annotation dans votre méthode de connexion pour spécifier le GET.
@RequestMapping (value = "/ login" , method = RequestMethod.GET)
ou
@GetMapping ("login")
qui est plus recommandé (soyez prudent sur le ' / 'caractère je pense que dans celui-ci vous n'en avez pas besoin)
J'espère que cela aide!
Je crois avoir trouvé la réponse, même si je ne suis pas sûr à 100% de comprendre la documentation. Tout ce que j'ai fait a été de changer "defaultSuccessUrl (" / home ")" en "defaultSuccessUrl (" / home ", true)", et cela m'a donné le résultat dont j'avais besoin. La documentation à ce sujet est disponible ici: https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config /annotation/web/configurers/AbstractAuthenticationFilterConfigurer.html#defaultSuccessUrl-java.lang.String-boolean-
Et un autre article similaire peut être trouvé ici: la sécurité du printemps ne fonctionne pas rediriger après une connexion réussie
Selon la documentation defaultSuccessUrl (String defaultSuccessUrl, boolean alwaysUse)
Spécifie où les utilisateurs iront après s'être authentifiés avec succès s'ils ne l'ont pas fait visité une page sécurisée avant de s'authentifier ou alwaysUse est vrai.
Maintenant, explorons du code,
AbstractAuthenticationFilterConfigurer code >
se compose des méthodes defaultSuccessUrl (String defaultSuccessUrl)
et defaultSuccessUrl (String defaultSuccessUrl, boolean alwaysUse)
1.defaultSuccessUrl (String defaultSuccessUrl)
Ceci est un raccourci pour appeler defaultSuccessUrl (String).
if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) { requestCache.removeRequest(request, response); super.onAuthenticationSuccess(request, response, authentication); return; }
" 2 " defaultSuccessUrl (String defaultSuccessUrl, booléen alwaysUse)
public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) { SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler(); handler.setDefaultTargetUrl(defaultSuccessUrl); handler.setAlwaysUseDefaultTargetUrl(alwaysUse); this.defaultSuccessHandler = handler; return successHandler(handler); }
Comme nous pouvons le voir, la méthode 1 appelle finalement la méthode 2 avec alwaysUse as false , en utilisant les méthodes 2 avec alwaysUse as true , nous définissons explicitement le paramètre qui est ensuite utilisé dans SavedRequestAwareAuthenticationSuccessHandler
a> comme suit
public final T defaultSuccessUrl(String defaultSuccessUrl) { return defaultSuccessUrl(defaultSuccessUrl, false); }
Spring ne vous redirigera pas en fonction de votre rôle, vous devez gérer la redirection manuellement, Il ne vous donnera que accès à celui-ci.
Jetez un œil:
@GetMapping("/redirect") public void getRedirect(HttpServletResponse resp, HttpServletRequest request) throws IOException { System.out.println("Auth: " + SecurityContextHolder.getContext().getAuthentication()); Authentication auth = SecurityContextHolder.getContext().getAuthentication(); System.out.println("Principal: " + auth.getPrincipal()); System.out.println("Authorities: " + auth.getAuthorities()); //get it from here OR System.out.println(request.isUserInRole("ROLE_USER")); // get it from Here as WELL (ONLY IF YOU HAVE A REQUEST) if (request.isUserInRole("ROLE_USER")) { resp.sendRedirect("/user"); } else if (request.isUserInRole("ROLE_ADMIN")) { resp.sendRedirect("/admin"); } }
Gestion des redirections /redirect
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin").hasRole("ADMIN") .antMatchers("/user").hasRole("USER") .antMatchers("/").permitAll() .and().formLogin().defaultSuccessUrl("/redirect") //endpoint to manage redirects .and().logout() .permitAll(); }
Gardez à l'esprit qu'il existe des différences de portée
hasRole ()
donne des autorités: [ROLE_ADMIN]
hasAuthority ()
renvoie Autorités: [ADMIN]
J'espère que cela vous aidera!
Après une connexion réussie, vous êtes correctement redirigé vers / home, n'est-ce pas? Si oui, après / home à quelle URL essayez-vous d'accéder.
Après une première connexion réussie après le démarrage de l'application, je suis redirigé vers «/ login» plutôt que «/ home» comme je le souhaite. Après la deuxième connexion réussie et à partir de là, je suis correctement redirigé vers "/ home". Je ne sais tout simplement pas pourquoi je suis redirigé vers "/ login" après la première tentative réussie.
Le code partagé semble fonctionner, pouvez-vous partager le lien GitHub si possible
Malheureusement je ne peux pas. Comment l'avez-vous testé? Lien?
Pouvez-vous vérifier les demandes dans l'onglet Réseau de la première tentative de connexion et partager l'image
J'ai partagé la question ci-dessus. Comme vous pouvez le voir, après la première connexion, je suis redirigé vers l'écran de connexion, mais après la seconde, je suis redirigé vers la page d'accueil.
pourriez-vous partager un code reproductible minimal?