Próbuję zintegrować rozszerzenie Spring Security SAML z Spring Boot .
W tej sprawie opracowałem kompletną aplikację przykładową. Jego kod źródłowy jest dostępny na GitHub:
Uruchamiając go jako aplikację Spring Boot (działającą na wbudowanym serwerze aplikacji SDK), WebApp działa dobrze.
Niestety ten sam proces AuthN w ogóle nie działa w Undertow / WildFly .
Według dzienników IdP faktycznie wykonuje proces AuthN : instrukcje mojej niestandardowej UserDetails
implementacji są poprawnie wykonywane. Pomimo wykonania, Spring nie konfiguruje i nie utrzymuje uprawnień dla bieżącego użytkownika.
@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;
}
}
Podczas debugowania dowiedziałem się, że problem zależy od FilterChainProxy
klasy. W czasie wykonywania atrybut FILTER_APPLIED
z ServletRequest
ma zerową wartość, tym samym Wiosna czyści 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);
}
}
W VMware vFabric tc Sever i Tomcat wszystko działa całkowicie dobrze. Czy masz pomysł na rozwiązanie tego problemu?
SecurityContextHolder.clearContext()
nie usuwa danych sesji. Usuwa ThreadLocal
przechowywanie kontekstu przed zwolnieniem wątku z powrotem do puli wątków. Chodzi mi o to, że zawsze powinno się to zdarzyć na końcu żądania, więc to, co widzisz, jest normalne i prawdopodobnie nie będzie przyczyną twojego problemu.
SecurityContextHolder
należy to wyczyścić po zgłoszeniu. Jedynym celem tego kodu jest przypadek zastosowania łańcucha filtrów więcej niż raz podczas tego samego żądania (w takim przypadku tylko oryginalny łańcuch powinien wyczyścić kontekst). Więc nie sądzę, żeby to był problem.