Spring Security SAML Uzantısını Spring Boot ile entegre etmeye çalışıyorum .
Konu hakkında eksiksiz bir örnek uygulama geliştirdim. Kaynak kodu GitHub'da mevcuttur:
Spring Boot uygulaması (SDK yerleşik Uygulama Sunucusu ile çalışan) olarak çalışarak WebApp sorunsuz çalışır.
Ne yazık ki, aynı AuthN süreci Undertow / WildFly'de hiç çalışmıyor .
Günlüklere göre, IdP aslında AuthN işlemini gerçekleştirir : özel UserDetailsuygulamamın talimatları doğru bir şekilde yürütülür. Yürütme akışına rağmen, Spring geçerli kullanıcı için ayrıcalıklar oluşturmaz ve sürdürmez.
@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;
}
}
Hata ayıklama sırasında, sorunun FilterChainProxysınıfa bağlı olduğunu öğrendim . Çalışma zamanında, özelliği, FILTER_APPLIEDbir ServletRequestbir olan boş böylece Spring temizler, değer 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);
}
}
On VMware vFabric tc Sever ve Tomcat , her şey tamamen iyi çalışır. Bu sorunun çözümü hakkında bir fikriniz var mı?
SecurityContextHolder.clearContext()oturum verilerini temizlemez. ThreadLocalBir iş parçacığını iş parçacığı havuzuna geri bırakmadan önce bağlamın depolanmasını kaldırır . Demek istediğim, bunun her zaman bir isteğin sonunda olması gerektiğidir, bu yüzden gördüğünüz şey normaldir ve probleminizin nedeni olması muhtemel değildir.
SecurityContextHolderbir istek sonrasında temizlenmelidir. Bu kodun tek amacı, filtre zincirinin aynı talep sırasında birden fazla kez uygulanmasıdır (bu durumda, yalnızca orijinal zincir bağlamı temizlemelidir). Yani bunun bir sorun olduğunu düşünmüyorum.