Spring Security on Wildfly: erro ao executar a cadeia de filtros

194

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 UserDetailsimplementaçã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("[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;
    }
}

Durante a depuração, descobri que o problema depende da FilterChainProxyclasse. No tempo de execução, o atributo FILTER_APPLIEDde ServletRequestpossui 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?

vdenotaris
fonte
2
Na maioria das situações, isso SecurityContextHolderdeve 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.
Shaun the Sheep
2
BTW, esse comportamento invalida o processo de logon sempre. Existe uma maneira de corrigi-lo, por exemplo, configurando corretamente meu software do AS?
precisa saber é o seguinte
1
Não sei o que você quer dizer com isso. Qual comportamento e como isso invalida o login? Limpar o contexto quando um encadeamento termina de manipular uma solicitação é um comportamento normal - é essencial evitar o vazamento de dados locais do encadeamento de volta para um conjunto de encadeamentos. Nesse ponto, o contexto geralmente deve ser armazenado em cache na sessão do usuário. Portanto, não deve invalidar um login.
Shaun the Sheep
2
Como descrito acima, após o SSO, o Application Server limpa os dados da sessão e os dados de autenticação. Isso ocorre apenas com o Wildfly: o mesmo código funciona bem com o Tomcat.
precisa saber é o seguinte
11
SecurityContextHolder.clearContext()não limpa os dados da sessão. Ele remove o ThreadLocalarmazenamento 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.
Shaun the Sheep (

Respostas:

7

Investigando o problema, notei que há alguma confusão com cookies e referências na solicitação de autenticação.

Atualmente, a autenticação wildfly funcionará se você alterar o contexto do aplicativo da web para o Contexto Raiz:

 <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>

Após reiniciar o wildfly e limpar os cookies, tudo deve funcionar conforme o esperado

nesteant
fonte
boa solução, se você é famoso com o WildFly e o JBOSS, você pode dar uma olhada nessa pergunta stackoverflow.com/questions/59006162/…
ZINE Mahmoud