4 votes

Spring Security Core authAjax, Comment ignorer le Referer ?

J'utilise Grails 1.3.7 et le dernier plugin spring-security-core. J'ai implémenté la méthode suivante dans mon LoginController :

def authAjax = {
   response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
   response.sendError HttpServletResponse.SC_UNAUTHORIZED
}

Et dans mon fichier JavaScript global, j'ai ce qui suit :

$.ajaxSetup({
   error: function(xhr, status, err) {
      if (xhr.status == 401) {
         // display a login form in a dialog
      }
   }
});

Le formulaire de connexion est le formulaire de connexion standard directement issu de la documentation du plugin. La seule différence est que je soumets mon formulaire en utilisant jQuery comme suit :

var params = $('#ajaxLoginForm').serialize();
$.post($('#ajaxLoginForm').attr('action'), params, function(jsonData) {
   if (jsonData.success) {
      $('#login-dialog').dialog('close');
   } else {
      alert('TODO: display errors');
   }
}, 'json');

Le problème est que la première fois que je clique sur le bouton de connexion, je semble m'authentifier correctement, mais la réponse du serveur est une redirection 302 basée sur l'en-tête de requête Referer. Le corps de mon $.post() n'est donc jamais exécuté. Je reçois du HTML au lieu de JSON. La méthode LoginController.ajaxSuccess n'est pas exécutée avant la deuxième soumission. J'ai lu et relu la documentation et je dois manquer quelque chose.

MISE À JOUR : Il semble que ce ne soit pas un problème de référent, puisque la deuxième fois que le formulaire est affiché, le référent est toujours là. Je ne comprends donc pas pourquoi je dois soumettre le formulaire deux fois pour que la méthode ajaxSuccess soit appelée.

6voto

Micah Craig Points 220

Lorsque vous tentez d'accéder à une ressource protégée sans autorisation, Spring Security enregistre cette demande dans votre session (http://static.springsource.org/spring-security/site/apidocs/org/springframework/security/web/savedrequest/DefaultSavedRequest.html), puis, lorsque vous vous authentifiez avec succès, il vous redirige vers cette demande. Vous pouvez probablement désactiver ce comportement de manière générale en configurant Spring Security, mais ce n'est probablement pas ce que vous souhaitez pour la plupart des flux de travail. Vous pourriez également supprimer explicitement la SavedRequest de la session dans votre méthode authAjax, mais là encore, ce n'est probablement pas la meilleure expérience pour l'utilisateur.

Je crois que LoginController.ajaxSuccess n'est activé que s'il n'y a pas de SavedRequest à rediriger, donc le HTML que vous recevez en retour devrait être le résultat de votre requête originale, qui n'était pas autorisée à ce moment-là. L'astuce consiste donc à utiliser la fonction que vous auriez utilisée pour traiter la requête originale comme méthode de succès pour votre soumission #ajaxLoginForm.

0voto

Peter Ledbrook Points 1611

Gregg, vous vous heurtez probablement au comportement par défaut du conteneur de servlets pour les réponses 401. Je vous recommande d'utiliser quelque chose comme :

def authAjax = {
    response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
    render status: 401, contentType: "application/json", {
    message = "You are not authorized for this page"
    }
}

Je ne l'ai pas testé, alors faites-moi savoir comment ça se passe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X