2016-01-07 5 views
0

Внедрение SingleSign с использованием Spring Security.Весенний контент безопасности заблокирован в iFrame

Мы столкнулись с странной ситуацией после того, как мы заменили аутентификацию на основе файлов cookie с использованием аутентификации на основе SAML, используя весеннюю безопасность.

Добавление SAMLContextProviderImpl в securityContext.xml, я вижу, что запрос перенаправляется бесконечно, то есть контекст добавляется 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.

Если обновить страницу, приложение загрузится нормально. Но он заблокирован только в первый раз.

Любая помощь по этому вопросу будет оценена по достоинству.

ответ

1

Я столкнулся с вашей проблемой во время моего поиска в Интернете, поскольку я испытывал ту же проблему. Причина этого в том, что SAMLContextProviderLB выполняет часть работы, но не охватывает ситуацию, когда ваше приложение находится внутри iframe.

Что происходит в этой ситуации, так это то, что исходный запрошенный URL-адрес, который защищен весной security saml, хранится в сеансе пользователя (при условии, что вы используете SavedRequestAwareAuthenticationSuccessHandler). Теперь, поскольку ваше приложение работает за балансировщиком нагрузки, которое, по-видимому, обрабатывает выгрузку ssl, приложение действительно видит URL как простой http, который хранится.

После успешного использования sso в idp утверждение отправляется на адрес acs в/saml/SSO/alias/{sp-entity-id}. Здесь SAMLContextProviderLB вступает в игру, и он отлично справляется с этим.

Затем весенняя безопасность (через SavedRequestAwareAuthenticationSuccessHandler) будет извлекать исходный запрошенный url, который он ранее хранил в сеансе, и перенаправляет его в это место. Здесь возникает проблема. Он сохранил URL как простой http, потому что это то, как ваше приложение увидело запрос, поскольку оно находится за балансировщиком нагрузки.

Что касается хрома, то это свидетельствует о некоторых не-https-активности и поэтому не говорит ни о чем.

Итак, решение состоит в том, чтобы сделать то же самое, что и SAMLContextProviderLB - в основном просто переписать http на https в URL. К сожалению, было невозможно просто расширить SavedRequestAwareAuthenticationSuccessHandler из-за того, что переменная requestCache является частной. Вместо этого просто скопируйте и вставьте этот класс - я просто добавил одну строку, чтобы заменить 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); 
    } 

} 

Надеюсь, что это поможет.

Смежные вопросы