Я пытаюсь интегрировать расширение Spring Security SAML с Spring Boot .
По этому поводу я разработал полный пример приложения. Его исходный код доступен на GitHub:
Запустив его как приложение Spring Boot (работающее со встроенным сервером приложений SDK), WebApp работает нормально.
К сожалению, тот же процесс AuthN совсем не работает в Undertow / WildFly .
Согласно журналам, IdP фактически выполняет процесс AuthN : инструкции моей пользовательской UserDetails
реализации выполняются правильно. Несмотря на ход выполнения, Spring не устанавливает и не сохраняет привилегии для текущего пользователя.
@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;
}
}
Во время отладки я обнаружил, что проблема зависит от FilterChainProxy
класса. Во время выполнения, атрибут FILTER_APPLIED
из ServletRequest
имеет нулевое значение, таким образом Spring очищает 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);
}
}
На VMware vFabric tc Sever и Tomcat все работает совершенно нормально. Есть ли у вас идеи по решению этой проблемы?
SecurityContextHolder.clearContext()
не очищает данные сеанса Он удаляет ThreadLocal
хранилище контекста до освобождения потока обратно в пул потоков. Я хочу сказать, что это всегда должно происходить в конце запроса, поэтому то, что вы видите, является нормальным явлением и вряд ли станет причиной вашей проблемы.
SecurityContextHolder
после запроса следует очистить. Единственная цель этого кода в том случае, если цепочка фильтров применяется более одного раза во время одного и того же запроса (в этом случае только исходная цепочка должна очищать контекст). Так что я не думаю, что это проблема.