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 UserDetails
implé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("jdoe@samplemail.com") != 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 FilterChainProxy
classe. Au moment de l'exécution, l'attribut FILTER_APPLIED
de ServletRequest
a 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?
SecurityContextHolder.clearContext()
n'efface pas les données de session. Il supprime le ThreadLocal
stockage 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.
SecurityContextHolder
doit ê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.