Estoy tratando de integrar Spring Security SAML Extension con Spring Boot .
Sobre el asunto, desarrollé una aplicación de muestra completa. Su código fuente está disponible en GitHub:
Al ejecutarlo como la aplicación Spring Boot (que se ejecuta en el servidor de aplicaciones integrado del SDK), la aplicación web funciona bien.
Desafortunadamente, el mismo proceso AuthN no funciona en absoluto en Undertow / WildFly .
Según los registros, el IdP realmente realiza el proceso AuthN : las instrucciones de mi UserDetails
implementación personalizada se ejecutan correctamente. A pesar del flujo de ejecución, Spring no configura y persiste los privilegios para el usuario actual.
@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 la depuración, descubrí que el problema depende de la FilterChainProxy
clase. En tiempo de ejecución, el atributo FILTER_APPLIED
de ServletRequest
tiene un valor nulo , por lo que Spring borra el 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);
}
}
En VMware vFabric tc Sever y Tomcat , todo funciona perfectamente. ¿Tienes alguna idea sobre cómo resolver este problema?
SecurityContextHolder.clearContext()
no borra los datos de la sesión. Elimina el ThreadLocal
almacenamiento del contexto antes de volver a liberar un subproceso en el grupo de subprocesos. Mi punto es que esto siempre debe suceder al final de una solicitud, por lo que lo que está viendo es normal y no es probable que sea la causa de su problema.
SecurityContextHolder
debe borrar después de una solicitud. El único propósito de ese código es en caso de que la cadena de filtro se aplique más de una vez durante la misma solicitud (en cuyo caso, solo la cadena original debe borrar el contexto). Entonces no creo que sea un problema.