Spring Security on Wildfly: Fehler beim Ausführen der Filterkette

194

Ich versuche, die Spring Security SAML-Erweiterung in Spring Boot zu integrieren .

Zu diesem Thema habe ich eine vollständige Beispielanwendung entwickelt. Der Quellcode ist auf GitHub verfügbar:

Durch Ausführen als Spring Boot-Anwendung (ausgeführt auf dem in SDK integrierten Anwendungsserver) funktioniert die WebApp einwandfrei.

Leider funktioniert der gleiche AuthN-Prozess auf Undertow / WildFly überhaupt nicht .

Gemäß den Protokollen führt der IdP tatsächlich den AuthN- Prozess aus: Die Anweisungen meiner benutzerdefinierten UserDetailsImplementierung werden korrekt ausgeführt. Trotz des Ausführungsablaufs richtet Spring die Berechtigungen für den aktuellen Benutzer nicht ein und behält sie nicht bei.

@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;
    }
}

Beim Debuggen habe ich herausgefunden, dass das Problem von der FilterChainProxyKlasse abhängt . Zur Laufzeit hat das Attribut FILTER_APPLIEDvon ServletRequesteinen Nullwert , daher löscht Spring das 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);
    }
}

Unter VMware vFabric tc Sever und Tomcat funktioniert alles einwandfrei . Haben Sie eine Idee zur Lösung dieses Problems?

vdenotaris
quelle
2
In den meisten Situationen SecurityContextHoldersollte das nach einer Anfrage gelöscht werden. Der einzige Zweck dieses Codes besteht darin, dass die Filterkette während derselben Anforderung mehrmals angewendet wird (in diesem Fall sollte nur die ursprüngliche Kette den Kontext löschen). Ich denke also nicht, dass das ein Problem ist.
Shaun das Schaf
2
Übrigens macht dieses Verhalten den Anmeldevorgang jedes Mal ungültig. Gibt es eine Möglichkeit, dies zu beheben, indem Sie beispielsweise meine Software des AS ordnungsgemäß konfigurieren?
Vdenotaris
1
Ich bin mir nicht sicher, was du damit meinst. Welches Verhalten und wie macht es die Anmeldung ungültig? Das Löschen des Kontexts, wenn ein Thread die Bearbeitung einer Anforderung abgeschlossen hat, ist ein normales Verhalten. Es ist wichtig zu verhindern, dass threadlokale Daten zurück in einen Thread-Pool gelangen. Zu diesem Zeitpunkt sollte der Kontext normalerweise in der Sitzung des Benutzers zwischengespeichert werden. Ein Login sollte also nicht ungültig werden.
Shaun das Schaf
2
Wie oben beschrieben, löscht der Anwendungsserver nach dem SSO Sitzungsdaten und Authentifizierungsdaten. Dies tritt nur bei Wildfly auf: Der gleiche Code funktioniert auch bei Tomcat.
Vdenotaris
11
SecurityContextHolder.clearContext()Sitzungsdaten werden nicht gelöscht. Der ThreadLocalSpeicher des Kontexts wird entfernt, bevor ein Thread wieder in den Thread-Pool freigegeben wird. Mein Punkt ist, dass dies immer am Ende einer Anfrage geschehen sollte. Was Sie also sehen, ist normal und wahrscheinlich nicht die Ursache Ihres Problems.
Shaun das Schaf

Antworten:

7

Bei der Untersuchung des Problems ist mir aufgefallen, dass die Authentifizierungsanforderung mit Cookies und Verweisen in Konflikt gerät.

Derzeit funktioniert die Wildfly-Authentifizierung, wenn Sie den Webanwendungskontext in den Stammkontext ändern:

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

Nach dem Neustart von Wildfly und dem Löschen von Cookies sollten alle wie erwartet funktionieren

Nesteant
quelle
Gute Lösung, wenn Sie mit WildFly und JBOSS berühmt sind, können Sie einen Blick auf diese Frage werfen. stackoverflow.com/questions/59006162/…
ZINE Mahmoud