Saya mencoba untuk mengintegrasikan Spring Security SAML Extension dengan Spring Boot .
Tentang masalah ini, saya memang mengembangkan aplikasi sampel lengkap. Kode sumbernya tersedia di GitHub:
Dengan menjalankannya sebagai aplikasi Boot Musim Semi (berjalan melawan Server Aplikasi bawaan SDK), WebApp berfungsi dengan baik.
Sayangnya, proses AuthN yang sama tidak bekerja sama sekali di Undertow / WildFly .
Menurut log, IdP benar-benar melakukan proses AuthN : instruksi UserDetails
implementasi kustom saya dijalankan dengan benar. Meskipun alur eksekusi, Spring tidak mengatur dan mempertahankan hak istimewa untuk pengguna saat ini.
@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;
}
}
Saat debugging, saya menemukan masalahnya bergantung pada FilterChainProxy
kelas. Pada saat runtime, atribut FILTER_APPLIED
dari ServletRequest
memiliki nilai nol , sehingga Spring membersihkan 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);
}
}
Pada VMware vFabric tc Sever dan Tomcat , semuanya bekerja dengan baik. Apakah Anda punya ide untuk menyelesaikan masalah ini?
SecurityContextHolder.clearContext()
tidak menghapus data sesi. Ini menghapus ThreadLocal
penyimpanan konteks sebelum melepaskan utas kembali ke kumpulan utas. Maksud saya adalah bahwa ini harus selalu terjadi pada akhir permintaan, jadi apa yang Anda lihat adalah normal dan tidak mungkin menjadi penyebab masalah Anda.
SecurityContextHolder
harus dibersihkan setelah permintaan. Satu-satunya tujuan dari kode itu adalah dalam kasus rantai filter diterapkan lebih dari satu kali selama permintaan yang sama (dalam hal ini, hanya rantai asli yang harus menghapus konteksnya). Jadi saya tidak berpikir itu masalah.