Spring Security sur Wildfly: erreur lors de l'exécution de la chaîne de filtrage

194

J'essaie d'intégrer l' extension Spring Security SAML à Spring Boot .

À ce sujet, j'ai développé un exemple d'application complet. Son code source est disponible sur GitHub:

En l'exécutant en tant qu'application Spring Boot (exécutée sur le serveur d'applications intégré du SDK), la WebApp fonctionne correctement.

Malheureusement, le même processus AuthN ne fonctionne pas du tout sur Undertow / WildFly .

Selon les journaux, l'IdP effectue réellement le processus AuthN : les instructions de mon UserDetailsimplémentation personnalisée sont correctement exécutées. Malgré le flux d'exécution, Spring ne configure pas et ne conserve pas les privilèges de l'utilisateur actuel.

@Component
public class SAMLUserDetailsServiceImpl implements SAMLUserDetailsService {

    // Logger
    private static final Logger LOG = LoggerFactory.getLogger(SAMLUserDetailsServiceImpl.class);

    @Override
    public Object loadUserBySAML(SAMLCredential credential)
            throws UsernameNotFoundException, SSOUserAccountNotExistsException {
        String userID = credential.getNameID().getValue();
        if (userID.compareTo("[email protected]") != 0) {     // We're simulating the data access.
            LOG.warn("SSO User Account not found into the system");
            throw new SSOUserAccountNotExistsException("SSO User Account not found into the system", userID);
        }
        LOG.info(userID + " is logged in");
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
        authorities.add(authority);
        ExtUser userDetails = new ExtUser(userID, "password", true, true, true,
                true, authorities, "John", "Doe");
        return userDetails;
    }
}

Lors du débogage, j'ai découvert que le problème dépend de la FilterChainProxyclasse. Au moment de l'exécution, l'attribut FILTER_APPLIEDde ServletRequesta une valeur nulle , donc Spring efface le SecurityContextHolder.

private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
    if (clearContext) {
        try {
            request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
            doFilterInternal(request, response, chain);
        } finally {
            SecurityContextHolder.clearContext();
            request.removeAttribute(FILTER_APPLIED);
        }
    } else {
        doFilterInternal(request, response, chain);
    }
}

Sur VMware vFabric tc Sever et Tomcat , tout fonctionne parfaitement. Avez-vous une idée de la résolution de ce problème?

vdenotaris
la source
2
Dans la plupart des situations, le SecurityContextHolderdoit être effacé après une demande. Le seul objectif de ce code est dans le cas où la chaîne de filtrage est appliquée plusieurs fois au cours de la même demande (auquel cas, seule la chaîne d'origine doit effacer le contexte). Je ne pense donc pas que ce soit un problème.
Shaun le mouton
2
BTW, ce comportement invalide le processus de connexion à chaque fois. Existe-t-il un moyen de le corriger, par exemple en configurant correctement mon logiciel de l'AS?
vdenotaris
1
Je ne sais pas ce que tu veux dire par là. Quel comportement et comment invalide-t-il la connexion? Effacer le contexte lorsqu'un thread a fini de traiter une demande est un comportement normal - il est essentiel d'empêcher la fuite de données locales au thread vers un pool de threads. À ce stade, le contexte doit généralement être mis en cache dans la session de l'utilisateur. Cela ne devrait donc pas invalider une connexion.
Shaun the Sheep
2
Comme décrit ci-dessus, après l'authentification unique, le serveur d'applications efface les données de session et les données d'authentification. Cela se produit uniquement avec Wildfly: le même code fonctionne correctement avec Tomcat.
vdenotaris
11
SecurityContextHolder.clearContext()n'efface pas les données de session. Il supprime le ThreadLocalstockage du contexte avant de libérer un thread dans le pool de threads. Mon point est que cela devrait toujours se produire à la fin d'une demande, donc ce que vous voyez est normal et n'est pas susceptible d'être la cause de votre problème.
Shaun the Sheep

Réponses:

7

En enquêtant sur le problème, j'ai remarqué qu'il y avait des problèmes avec les cookies et les référents dans la demande d'authentification.

Actuellement, l'authentification Wildfly fonctionnera si vous changez le contexte de l'application Web en contexte racine:

 <server name="default-server" default-host="webapp">
     <http-listener name="default" socket-binding="http"/>
     <host name="default-host" alias="localhost" default-web-module="sso.war"/>
 </server>

Après avoir redémarré Wildfly et effacé les cookies, tout devrait fonctionner comme prévu

nesteant
la source
belle solution si vous êtes célèbre avec WildFly et JBOSS pouvez-vous jeter un coup d'œil à cette question stackoverflow.com/questions/59006162/…
ZINE Mahmoud