Sto cercando di integrare l' estensione SAML di Spring Security con Spring Boot .
A proposito, ho sviluppato un'applicazione di esempio completa. Il suo codice sorgente è disponibile su GitHub:
Eseguendolo come applicazione Spring Boot (in esecuzione sull'SDK Application Server integrato), WebApp funziona correttamente.
Sfortunatamente, lo stesso processo AuthN non funziona affatto su Undertow / WildFly .
Secondo i registri, l'IdP esegue effettivamente il processo AuthN : le istruzioni della mia UserDetails
implementazione personalizzata sono eseguite correttamente. Nonostante il flusso di esecuzione, Spring non imposta e mantiene i privilegi per l'utente corrente.
@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;
}
}
Durante il debug, ho scoperto che il problema si basa sulla FilterChainProxy
classe. In fase di esecuzione, l'attributo FILTER_APPLIED
di ServletRequest
ha un valore nullo , quindi Spring cancella il valore 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);
}
}
Su VMware vFabric tc Sever e Tomcat , tutto funziona perfettamente. Hai idea di come risolvere questo problema?
SecurityContextHolder.clearContext()
non cancella i dati della sessione. Rimuove l' ThreadLocal
archiviazione del contesto prima di rilasciare nuovamente un thread nel pool di thread. Il mio punto è che questo dovrebbe accadere sempre alla fine di una richiesta, quindi quello che stai vedendo è normale e non è probabile che sia la causa del tuo problema.
SecurityContextHolder
dovrebbe essere cancellato dopo una richiesta. L'unico scopo di quel codice è nel caso in cui la catena di filtri sia applicata più di una volta durante la stessa richiesta (nel qual caso, solo la catena originale dovrebbe cancellare il contesto). Quindi non penso che sia un problema.