Tôi đang cố gắng tích hợp Spring Security SAML Extension với Spring Boot .
Về vấn đề này, tôi đã phát triển một ứng dụng mẫu hoàn chỉnh. Mã nguồn của nó có sẵn trên GitHub:
Bằng cách chạy nó dưới dạng ứng dụng Spring Boot (chạy với Máy chủ ứng dụng tích hợp SDK), WebApp hoạt động tốt.
Thật không may, quá trình AuthN tương tự hoàn toàn không hoạt động trên Undertow / WildFly .
Theo nhật ký, IdP thực sự thực hiện quy trình AuthN : các hướng dẫn UserDetails
thực hiện tùy chỉnh của tôi được thực thi chính xác. Bất chấp luồng thực thi, Spring không thiết lập và duy trì các đặc quyền cho người dùng hiện tại.
@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;
}
}
Trong khi gỡ lỗi, tôi phát hiện ra vấn đề phụ thuộc vào FilterChainProxy
lớp. Trong thời gian chạy, thuộc tính FILTER_APPLIED
của ServletRequest
có giá trị null , do đó Spring xóa 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);
}
}
Trên VMware vFoven tc Sever và Tomcat , mọi thứ hoạt động hoàn toàn tốt. Bạn có bất cứ ý tưởng về việc giải quyết vấn đề này?
SecurityContextHolder.clearContext()
dữ liệu phiên không rõ ràng. Nó loại bỏ việc ThreadLocal
lưu trữ bối cảnh trước khi phát hành một luồng trở lại nhóm luồng. Quan điểm của tôi là điều này sẽ luôn xảy ra vào cuối yêu cầu, vì vậy những gì bạn đang thấy là bình thường và không có khả năng là nguyên nhân của vấn đề của bạn.
SecurityContextHolder
cần được xóa sau khi yêu cầu. Mục đích duy nhất của mã đó là trong trường hợp chuỗi bộ lọc được áp dụng nhiều lần trong cùng một yêu cầu (trong trường hợp đó, chỉ chuỗi gốc sẽ xóa ngữ cảnh). Vì vậy, tôi không nghĩ đó là một vấn đề.