2014-04-30 58 views
2

我的问题似乎有点奇怪,但我想更好地理解Spring Security的工作原理。定义HTTP路由仅为Spring Security提供“内部”请求

我有一个场景如下...

通过使用春季安全春SAML,我定义的切入点,一些模式和过滤器,以妥善管理HTTP请求

<!-- Secured pages --> 
<security:http entry-point-ref="samlEntryPoint" 
    use-expressions="true"> 
    <security:intercept-url pattern="/" access="permitAll" /> 
    <security:intercept-url pattern="/saml/**" access="permitAll" /> 
    <security:intercept-url pattern="/metadata" access="permitAll" /> 
    <security:intercept-url pattern="/metadata/**" access="permitAll" /> 
    <security:intercept-url pattern="/info" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/signup/sso" access="permitAll" /> 
    <security:custom-filter before="FIRST" 
     ref="metadataGeneratorFilter" /> 
    <security:custom-filter after="BASIC_AUTH_FILTER" 
     ref="samlFilter" /> 
</security:http> 

<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy"> 
    <security:filter-chain-map request-matcher="ant"> 
     <security:filter-chain pattern="/saml/login/**" 
      filters="samlEntryPoint" /> 
     <security:filter-chain pattern="/saml/logout/**" 
      filters="samlLogoutFilter" /> 
     <security:filter-chain pattern="/saml/metadata/**" 
      filters="metadataDisplayFilter" /> 
     <security:filter-chain pattern="/saml/SSO/**" 
      filters="samlWebSSOProcessingFilter" /> 
     <security:filter-chain pattern="/saml/SSOHoK/**" 
      filters="samlWebSSOHoKProcessingFilter" /> 
     <security:filter-chain pattern="/saml/SingleLogout/**" 
      filters="samlLogoutProcessingFilter" /> 
     <security:filter-chain pattern="/saml/discovery/**" 
      filters="samlIDPDiscovery" /> 
    </security:filter-chain-map> 
</bean> 

然后,我还定义了一个的IdP发现服务

<!-- IDP Discovery Service --> 
<bean id="samlIDPDiscovery" class="org.springframework.security.saml.SAMLDiscovery"> 
    <property name="idpSelectionPath" value="/sso/idpSelection" /> 
</bean> 

最后,我实现了一个网络控制器服务的HTTP请求/sso/idpSelection

@Controller 
@RequestMapping("/sso") 
public class SSOController { 
    // Logger 
    private static final Logger LOG = LoggerFactory.getLogger(SSOController.class); 

    @Autowired 
    private ServletContext servletContext; 

    @RequestMapping(value = "/idpSelection", method = RequestMethod.GET) 
    public String idpSelection(HttpServletRequest request, Model model) {   
     WebApplicationContext context = WebApplicationContextUtils 
       .getWebApplicationContext(request.getServletContext()); 
     MetadataManager metadataManager = context.getBean("metadata", MetadataManager.class); 
     Set<String> idps = metadataManager.getIDPEntityNames(); 
     for (String idp : idps) 
      LOG.info("Configured Identity Provider for SSO: " + idp); 
     model.addAttribute("idp", idps); 
     return "sso/idpselection"; 
    } 
} 

当匿名用户尝试访问受保护页面时,过滤器会重定向他的请求t到/saml/discovery,因此IdP发现服务调用控制器/sso/idpSelection

很明显,/sso/idpSelection只能由IdP发现服务使用,因为内部的资源。

有没有办法拒绝直接访问请求(例如通过浏览器),但允许同时处理内部进程的路由?

回答

2

SAMLDiscovery在将用户发送到/ sso/idpSelection时进行转发。这意味着,你可以访问的页面直接使用编程禁止用户:

@RequestMapping(value = "/idpSelection", method = RequestMethod.GET) 
public String idpSelection(HttpServletRequest request, Model model) { 
    if (request.getAttribute("javax.servlet.forward.request_uri") == null) { 
     // Deny access 
    } 
    ... 
} 

属性“javax.servlet.forward.request_uri”是由集装箱通话过程中自动设置为RequestDispatcher的的前进方法,因此不会直接请求。该功能自Servlet 2.4开始提供。