Я намагаюся інтегрувати розширення 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
слід очистити після запиту. Єдине призначення цього коду полягає в тому випадку, якщо ланцюг фільтрів застосовується більше одного разу під час одного запиту (у цьому випадку контекст повинен очищати лише початковий ланцюг). Тому я не думаю, що це питання.