【问题标题】:Spring Security content blocked in iFrame在 iFrame 中阻止 Spring Security 内容
【发布时间】:2016-04-11 15:59:07
【问题描述】:

使用 Spring Security 实现 SingleSign。

在我们使用 Spring Security 将基于 cookie 的身份验证替换为基于 SAML 的身份验证后,我们遇到了一个奇怪的情况。

在 securityContext.xml 中添加 SAMLContextProviderImpl,我看到请求无限期地重定向,即上下文被附加 n 次。

  bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"/>

因此我将其替换为

  <bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderLB">
        <property name="scheme" value="https"/>
        <property name="serverName" value="ServerName"/>
        <property name="serverPort" value="43"/>
        <property name="includeServerPortInRequestURL" value="false"/>
        <property name="contextPath" value="/appcontext"/>
    </bean>

使用反向代理添加 ContextProvider 后,我没有看到多重重定向。上下文已正确加载。但是在 chrome 和 firefox 中,我看到应用程序未正确加载,并且从开发人员工具中我看到错误: 混合内容:“https://xportal/tools”处的页面通过 HTTPS 加载,但请求了不安全的表单操作“http://xportal/tools”。此请求已被阻止;内容必须通过 HTTPS 提供。

如果我们刷新页面,应用就会正常加载。但它只在第一次被阻止。

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: iframe spring-security single-sign-on


    【解决方案1】:

    我在谷歌搜索时遇到了您的问题,因为我遇到了同样的问题。发生这种情况的原因是因为 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);
        }
    
    }
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 2016-05-04
      • 2021-10-05
      相关资源
      最近更新 更多