我在谷歌搜索时遇到了您的问题,因为我遇到了同样的问题。发生这种情况的原因是因为 SAMLContextProviderLB 做了部分工作,但它没有涵盖您的应用位于 iframe 内的情况。
在这种情况下发生的情况是,受 spring security saml 保护的原始请求 url 存储在用户的会话中(假设您使用的是 SavedRequestAwareAuthenticationSuccessHandler)。现在,因为您的应用程序在负载均衡器后面运行,该负载均衡器可能正在处理卸载您的应用程序的 ssl,因此您的应用程序实际上将 url 视为纯 http,这是存储的内容。
在 idp 成功 sso 后,断言将发布到位于 /saml/SSO/alias/{sp-entity-id} 的 acs url。这就是 SAMLContextProviderLB 发挥作用的地方,它可以很好地处理它。
然后 spring security(通过 SavedRequestAwareAuthenticationSuccessHandler)将检索它先前存储在会话中的原始请求 url,并将重定向到该位置。这就是问题发生的地方。它将 url 存储为纯 http,因为这是您的应用程序看到请求的方式,因为它位于负载均衡器后面。
就 chrome 而言,它目睹了一些非 https 活动,因此没有办法。
因此,解决方案是做与 SAMLContextProviderLB 相同的事情——基本上只是将 url 中的 http 重写为 https。不幸的是,由于 requestCache 变量是私有的,因此无法简单地扩展 SavedRequestAwareAuthenticationSuccessHandler。相反,只需复制并粘贴此类 - 我刚刚添加了一行以将 http 替换为 https。
package com.blah;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;
public class SavedRequestAwareAuthenticationSuccessHandlerLB extends SimpleUrlAuthenticationSuccessHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
super.onAuthenticationSuccess(request, response, authentication);
return;
}
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl()
|| (targetUrlParameter != null && StringUtils.hasText(request
.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.onAuthenticationSuccess(request, response, authentication);
return;
}
clearAuthenticationAttributes(request);
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
targetUrl = StringUtils.replace(targetUrl, "http://", "https://");
logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
}
希望对您有所帮助。