配置SpringSecurity 3.2.5针对不同登录页面的多个http标记

时间:2014-09-17 10:10:27

标签: java xml spring-mvc spring-security

我目前正在探索为不同用户提供两个单独登录页面的可能性。

我现在可以根据这两页设置大多数网址。但是,我现在遇到了入口点ref和CONCURRENT_SESSION_FILTER的配置问题。

对于此安全版本,(LoginUrlAuthenticationEntryPoint.class - loginFormUrl ConcurrentSessionFilter.class - expiredUrl)不推荐使用该属性的setter方法,并使用在xml中设置的构造函数注入。

所以我想到两种解决这个问题的方法: 1.覆盖或注入两个类并根据条件更改url基础? 2.编写一个单独的http标记,读取特定的url模式并相应地应用配置。

提前致谢。工作代码如下:

<security:global-method-security pre-post-annotations="enabled" />  
<security:http auto-config="false"  use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <security:intercept-url pattern="/*" requires-channel="any"/>
    <security:intercept-url pattern="/**/*.json*" requires-channel="any"/>
    <security:intercept-url pattern="/**/dashboard/**" requires-channel="https"/>
    <security:intercept-url pattern="/**/rest/**" requires-channel="https"/>
    <security:intercept-url pattern="/**/cart/**" requires-channel="https"/>
    <security:intercept-url pattern="/**/customer/**" requires-channel="any"/>
    <security:intercept-url pattern="/**/api/**" requires-channel="any"/>
    <security:intercept-url pattern="/api/**" access="permitAll"/>
    <security:intercept-url pattern="/dashboard/signin" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/dashboard/signup" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/rest/signin" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/rest/signup" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/denied" access="permitAll"/>
    <security:access-denied-handler error-page="/denied"/>
    <security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
    <security:custom-filter before="FORM_LOGIN_FILTER" ref="customDeveloperPasswordAutenticationFilter"/>
    <security:custom-filter after="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
    <security:logout  logout-url="/j_spring_security_logout"  success-handler-ref="customLogoutSuccessHandler"/>
</security:http> 

我想要实现的代码是:

<security:global-method-security pre-post-annotations="enabled" />  
<security:http auto-config="false"  use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <security:intercept-url pattern="/*" requires-channel="any"/>
    <security:intercept-url pattern="/**/*.json*" requires-channel="any"/>
    <security:intercept-url pattern="/**/dashboard/**" requires-channel="https"/>
    <security:intercept-url pattern="/**/cart/**" requires-channel="https"/>
    <security:intercept-url pattern="/**/customer/**" requires-channel="any"/>
    <security:intercept-url pattern="/**/api/**" requires-channel="any"/>
    <security:intercept-url pattern="/api/**" access="permitAll"/>
    <security:intercept-url pattern="/dashboard/signin" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/dashboard/signup" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/denied" access="permitAll"/>
    <security:access-denied-handler error-page="/denied"/>
    <security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
    <security:custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
    <security:logout  logout-url="/j_spring_security_logout_user"  success-handler-ref="customLogoutSuccessHandlerUser"/>
</security:http> 

<security:http auto-config="false"  use-expressions="true" entry-point-ref="restUrlAuthenticationEntryPoint">
    <security:intercept-url pattern="/**/rest/**" requires-channel="https"/>
    <security:intercept-url pattern="/rest/signin" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/rest/signup" requires-channel="https" access="permitAll"/>
    <security:intercept-url pattern="/denied" access="permitAll"/>
    <security:access-denied-handler error-page="/denied"/>
    <security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="restConcurrencyFilter" />
    <security:custom-filter position="FORM_LOGIN_FILTER" ref="customDeveloperPasswordAutenticationFilter"/>
    <security:logout  logout-url="/j_spring_security_logout_developer"  success-handler-ref="customLogoutSuccessHandlerDeveloper"/>
</security:http> 

<security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="customUserDetailsService">
            <security:password-encoder ref="customPasswordEncoder"/>
        </security:authentication-provider>
</security:authentication-manager>

<bean id='customUserDetailsService' class='sg.oddlefnb.common.security.CustomUserDetailServiceImpl'>
    <!-- use to DAO to switch for different condition -->
    <property name='userDao' ref='userDao' />  
    <property name='developerDao' ref='developerDao' />  
</bean>

然而,这无法运行..有什么建议吗?

1 个答案:

答案 0 :(得分:0)

您不应该尝试这样做,它不是 spring安全方式。也许你可以成功(即使我怀疑你可以......)但是写作和维护都很难。

您可以在单个配置中拥有多个<http>块,但是当您想要将不同的过滤器链应用于不同的URL块时。

您可能有不同的登录页面(以及不同的身份验证方法:登录页面,基本身份验证,ldap,自定义...)。但春天的方式是分离身份验证和访问控制。因此,当用户通过身份验证时,其身份验证将存储在会话中,并将用于所有后续请求(直到会话结束)。在您的示例中,如果有人在身份验证之前要求用户页面,则将重定向到用户登录页面,作为用户进行身份验证并获取其页面。但是如果他在下一个请求中要求开发者页面,那么Spring安全性会在会话中找到一个有效的身份验证,允许作为访问规则的permitAll,并允许页面...我认为这不是你想要的!

执行所需操作的Spring安全方法是使用角色。简单的方法是拥有一个页面,并将角色存储在数据库中(或存储在内存存储中以进行开发和测试)。您可以使用访问规则中的角色。您可以在Spring Security Reference Manual中找到许多示例。

根据OP评论编辑:

根据使用的登录页面分配角色的情况并不常见,但可以这样做。您只需要定义两个不同的AuthenticationManager bean,并明确地将它们分配给您声明登录页面的两个不同的<http>块。在一个中,您明确地影响ROLE_USER授予的权限,而另一个ROLE_DEVELOPPER授权。您可以手动手动通过继承ProviderManager并在两者中使用相同的AuthenticationProviderS,或者您可以使用普通ProviderManager并自定义UserDetailsService AuthenticationProviderS的豆子。如果您展示了当前的<authentication-manager>集团,我可以轻松提出完整的解决方案。

一旦你拥有不同的角色,很容易将所有访问控制放在一个<http>块中,其中包含所有<security:intercept-url .../>