Estou tentando integrar o Spring Security SAML Extension ao Spring Boot .
Sobre o assunto, desenvolvi um aplicativo de amostra completo. Seu código fonte está disponível no GitHub:
Ao executá-lo como aplicativo Spring Boot (executando no Application Server interno do SDK), o WebApp funciona bem.
Infelizmente, o mesmo processo AuthN não funciona no Undertow / WildFly .
De acordo com os logs, o IdP realmente executa o processo AuthN : as instruções da minha UserDetails
implementação personalizada são executadas corretamente. Apesar do fluxo de execução, o Spring não configura e persiste os privilégios para o usuário atual.
@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 a depuração, descobri que o problema depende da FilterChainProxy
classe. No tempo de execução, o atributo FILTER_APPLIED
de ServletRequest
possui um valor nulo , portanto, o Spring limpa o 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);
}
}
No VMware vFabric tc Sever e Tomcat , tudo funciona totalmente bem. Você tem alguma ideia de como resolver esse problema?
SecurityContextHolder.clearContext()
não limpa os dados da sessão. Ele remove o ThreadLocal
armazenamento do contexto antes de liberar um encadeamento de volta ao conjunto de encadeamentos. O que quero dizer é que isso sempre deve acontecer no final de uma solicitação, portanto o que você está vendo é normal e provavelmente não será a causa do seu problema.
SecurityContextHolder
deve ser limpo após uma solicitação. O único objetivo desse código é no caso de a cadeia de filtros ser aplicada mais de uma vez durante a mesma solicitação (nesse caso, somente a cadeia original deve limpar o contexto). Então, eu não acho que isso seja um problema.