Printemps personnalisé AuthenticationFailureHandler
J'ai déjà essayer l'ensemble de la journée, pour obtenir mon personnalisée d'échec de l'authentification gestionnaire de travailler avec le Printemps 3.1.3.
Je pense qu'il est correctement configuré
<http use-expressions="true" disable-url-rewriting="true">
<intercept-url pattern="/rest/login" access="permitAll" />
<intercept-url pattern="/rest/**" access="isAuthenticated()" />
<intercept-url pattern="/index.html" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" />
<intercept-url pattern="/**" access="denyAll" />
<form-login username-parameter="user" password-parameter="pass" login-page="/rest/login"
authentication-failure-handler-ref="authenticationFailureHandler" />
</http>
<beans:bean id="authenticationFailureHandler" class="LoginFailureHandler" />
Mon application est ce
public class LoginFailureHandler implements AuthenticationFailureHandler {
private static final Logger log = LoggerFactory.getLogger(LoginFailureHandler.class);
public LoginFailureHandler() {
log.debug("I am");
}
@Autowired
private ObjectMapper customObjectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
log.debug("invalid login");
User user = new User();
user.setUsername("invalid");
try (OutputStream out = response.getOutputStream()) {
customObjectMapper.writeValue(out, user);
}
}
}
Dans la console je vois
2013-04-11 14:52:29,478 DEBUG LoginFailureHandler - I am
De sorte qu'il est chargé.
Avec un mauvais nom d'utilisateur ou mot de passe, quand un BadCredentialsException est jeté, je ne vois pas de connexion non valide.
La Méthode onAuthenticationFailure n'est jamais invoquée.
Au lieu de cela le service redirige le navigateur vers /repos/login, encore et encore...
Modifier
2013-04-11 15:47:26,411 DEBUG de.pentos.spring.LoginController - Incomming login chuck.norris, norris
2013-04-11 15:47:26,412 DEBUG o.s.s.a.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2013-04-11 15:47:26,415 DEBUG o.s.s.a.d.DaoAuthenticationProvider - Authentication failed: password does not match stored value
2013-04-11 15:47:26,416 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public de.pentos.spring.User de.pentos.spring.LoginController.login(de.pentos.spring.User)]: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-04-11 15:47:26,419 DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public de.pentos.spring.User de.pentos.spring.LoginController.login(de.pentos.spring.User)]: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-04-11 15:47:26,419 DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public de.pentos.spring.User de.pentos.spring.LoginController.login(de.pentos.spring.User)]: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-04-11 15:47:26,426 DEBUG o.s.web.servlet.DispatcherServlet - Could not complete request
org.springframework.security.authentication.BadCredentialsException: Bad credentials
Ce qui se passe dans le Mode de DÉBOGAGE
Où est mon erreur?
OriginalL'auteur Nabor | 2013-04-11
Vous devez vous connecter pour publier un commentaire.
L'on en juge par les journaux que vous avez joint je pense que vous avez fait une erreur dans la mise en œuvre du processus de connexion. Je ne peux pas être absolument sûr, mais je suppose que vous appelez
ProviderManager.authenticate()
dans votreLoginController
. La méthode renvoie uneBadCredentialsException
qui provoque Spring MVC exception d'un mécanisme de gestion pour le coup, ce qui bien sûr n'a pas de connaissances sur leAuthenticationFailureHandler
configuré pour le Printemps de Sécurité.De la connexion du contrôleur de vous devrait normalement servir un simple formulaire de connexion avec
action="j_spring_security_check" method="post"
. Lorsque l'utilisateur soumet que la forme, la configuration du filtre de sécurité (à savoirUsernamePasswordAuthenticationFilter
) intercepte la demande et gère l'authentification. Vous n'avez pas à mettre en œuvre que la logique de vous-même dans une méthode de contrôleur.Répondre à votre commentaire:
Vous utilisez
ProviderManager
(c'est la mise en œuvre de la autocâblésAuthenticationManager
interface). L'erreur que vous faites est que vous essayez de réécrire la logique déjà mis en œuvre et testés dans auth filtres. Ce qui est mauvais en soi, mais même cela est fait dans un mauvais sens. Vous sélectionnez juste quelques lignes à partir d'une logique complexe, et entre autres choses, vous oubliez par exemple, l'invocation de la session de stratégie (pour empêcher la fixation de session attaques, et la manipulation des séances simultanées). L'origine de la mise en œuvre appelle laAuthenticationFailureHandler
ainsi, vous avez aussi oublié dans votre méthode, c'est la raison du problème original de votre question.
Si vous vous retrouvez avec un non-testés, cassants solution au lieu de bien s'intégrer au cadre de tirer parti de son roboustness et de la pleine capacité. Comme je l'ai dit, la config vous avez posté votre réponse est une nette amélioration, car il utilise le cadre de filtre pour l'authentification. Garder cette config et supprimer
LoginController.login()
, il ne sera pas appelé de toute façon par les demandes envoyées à/rest/login
.Une question plus fondamentale est de savoir si c'est vraiment une bonne solution pour des sessions d'utilisation et en fonction du formulaire mécanisme de connexion si vous implémentez des services RESTful. (Sur le formulaire de connexion, je veux dire que le client envoie ses informations d'identification une fois quel que soit le format, puis est authentifié par un stateful session sur les requêtes suivantes.) Avec le RESTE des services, il est plus répandu, afin de garder tout apatrides, et de ré-identifier à chaque nouvelle demande par les informations portées par les en-têtes http.
La config vous avez posté votre réponse montre que les demandes envoyées à
/rest/login
sera intercepté par leUsernamePasswordAuthenticationFilter
(en raison de lafilterProcessesUrl
attribut). C'est sans importance si la demande est un POST de formulaire envoyé par un navigateur ou un PUT envoyé par un autre client REST. Pour sûr qu'ils ne seront pas frapper n'importe quelle méthode de gestionnaire d'mappé à la même URI, mais seront traitées par le ci-dessus mentionné filtre. C'est pourquoi votre config fonctionne maintenant (déjà votre méthode de gestionnaire de contrôle), et non pas parce que l'ordre de quelques haricots en xml, qui ne fait aucune différence.Je n'utilise pas ProviderManager comme vous pouvez le voir ici pastebin.com/N1m02Cyx Pouvez-vous expliquer à partir de cette classe, d'où mon erreur est?
Ma réponse aurait été trop long, veuillez vérifier mes mises à jour de réponse.
Je suis totalement perdu en essayant de le mettre en œuvre. J'ai lu tellement de nombreuses solutions différentes en essayant de trouver mon chemin vers cette jungle. Est-il possible de discuter de la solution plus en détail dans un chat?
OriginalL'auteur zagyi
C'est un problème avec la commande dans le security-app-context.xml.
Si j'ai d'abord définir tous mes haricots et puis tout le reste, il fonctionne.
J'ai essayé beaucoup de choses, ne soyez donc pas étonnant, qu'il semble un peu différente, alors que dans la question
OriginalL'auteur Nabor
N'a pas l'air mauvais pour moi. Avez-vous essayé d'utiliser le mode de débogage de votre IDE ?
Avez-vous vu ce genre de choses dans vos journaux :
La AuthenticationFailureHandler sera appelé automatiquement, uniquement si l'authentification est effectuée dans l'un des filtre d'authentification : UsernamePasswordAuthenticationFilter normalement dans votre cas.
Question bête, est la connexion gérée par le LoginController ?
Avez-vous mis des points d'arrêt dans UsernamePasswordAuthenticationFilter et AbstractAuthenticationProcessingfilter ?
OriginalL'auteur David Le Moing
(À la recherche à vos besoins), Vous n'avez pas besoin d'un custom AuthenticationFailureHandler le défaut SimpleUrlAuthenticationFailureHandler de Printemps et correctement mise en œuvre de AuthenticationProvider devrait servir l'objectif.
Si vous avez manipulé les Exceptions bien dans le Fournisseur d'Authentification:
Exemple De Logique:
Si nous voulons que les exceptions levées d'être réfléchie à l'interface du client, ajoutez les éléments suivants scriplet sur les JSP de répondre à authentification-non - -url="/login?authfailed=true"
OriginalL'auteur hemantvsn