3 votes

Comment combiner Spring web flow, Spring Security et un HandlerExceptionResolver comme SimpleMappingExceptionResolver ?

J'ai un SimpleMappingExceptionResolver pour rediriger chaque exception non gérée.

 @Bean public SimpleMappingExceptionResolver exceptionResolver() {
           SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
           resolver.setDefaultErrorView("general-error");
           resolver.setWarnLogCategory(TamponException.class.getName());
           return resolver;
}

Dès que j'ai implémenté la sécurité de Spring, je me suis rendu compte que je devais exclure l'élément AccessDeniedException :

resolver.setExcludedExceptions(AccessDeniedException.class);

Maintenant, j'implémente Spring Web Flow. SWF enveloppe les éléments essentiels AccessDeniedException en FlowExecutionException . Cette combinaison brise la sécurité de Spring, car les exceptions enveloppées sont désormais capturées par la fonction SimpleMappingExceptionResolver . Je pourrais aussi exclure les FlowExecutionException mais ce n'est pas ce que je veux.

Comment puis-je résoudre correctement ce problème ?

Ma prochaine idée serait d'implémenter un HandlerExceptionResolver dont les délégués resolveException() uniquement si l'exception non enveloppée n'est pas une AccessDeniedException . Mais je me demande s'il n'existe pas quelque chose de prêt à l'emploi pour la combinaison SWF, Security et un HandlerExceptionResolver.

2voto

malavock Points 271

J'utilise une configuration similaire à la vôtre, avec Spring webflow et Spring security. Pour gérer les exceptions, j'utilise le traitement webflow au lieu d'un SimpleMappingExceptionResolver et cela fonctionne très bien pour moi.

pour commencer, vous avez besoin d'un flux xml global qui gère les exceptions, ce flux sera utilisé comme "parent" de tous vos autres flux. ou vous pouvez également inclure directement la transition globale et le view-state dans vos flux :

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow
      http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
      abstract="true">

    <persistence-context/>

    <view-state id="generalException" view="../views/exception/generalException.xhtml">
        <on-entry>
            <evaluate expression="exceptionManager.extractMessages(flowExecutionException, rootCauseException)" result="viewScope.exc"/>
        </on-entry>
    </view-state>

    <global-transitions>
        <transition on-exception="java.lang.Exception" to="generalException"/>
    </global-transitions>

</flow>

La classe ExceptionManager n'est utilisée que pour formater l'exception de manière lisible, en particulier dans mon cas BatchUpdateException qui nécessite l'appel de la méthode next() pour connaître la source de l'exception :

@Service("exceptionManager")
public class ExceptionManagerImpl {

    public Map<String, String> extractMessages(Exception e, Exception root)
    {
        Map<String, String> out = new HashMap<String, String>();

        out.put("exc_message", e.getClass().toString() + ": " + e.getMessage());
        out.put("exc_details", formatStackTrace(e.getStackTrace()));
        out.put("root_message", root.getClass().toString() + ": " + root.getMessage());
        out.put("root_details", formatStackTrace(root.getStackTrace()));
        if (root instanceof BatchUpdateException)
        {
            out.put("batch_message", ((BatchUpdateException)root).getNextException().getClass().toString() + ": " + ((BatchUpdateException)root).getNextException().getMessage());
        }

        return out;
    }

    public String formatStackTrace(StackTraceElement[] elements)
    {
        String out = "";
        for (StackTraceElement ste: elements)
            out += ste.toString() + "<br/>";
        return out;
    }
}

de cette façon, toutes les exceptions non gérées seront affichées dans une page JSF, ou ce que vous utilisez pour les vues. L'exception AccessDeniedException passe normalement par la sécurité de Spring dans mon système avec cette implémentation. Vous pouvez également spécifier différents comportements pour différentes exceptions.

J'espère que cela vous aidera, passez une bonne journée,

Mattia

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