Web服务和用户的Spring安全性

时间:2014-06-18 14:39:19

标签: java spring security spring-mvc spring-security

我们有一个Web应用程序,我们希望使用spring security以两种不同的方式保护它:

1)使用登录表单进行身份验证且可以访问某些服务的用户。

2)使用摘要式身份验证保护的其他服务(用户+密码在请求的标头中传递) - 由其他Web应用程序使用,因此没有登录表单。

这些都是自己的,但我们无法让他们在同一个网络应用中工作。 当我们尝试使用两个xml运行webapp时,我们会收到以下错误:

A universal match pattern ('/**') is defined  before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration

用户的security.xml:

<security:http use-expressions="true">
    <security:intercept-url pattern="/user/login"
        access="permitAll" />
    ...
    <security:intercept-url pattern="/**"
        access="isAuthenticated()" />

    <security:form-login
        authentication-success-handler-ref="userAuthenticationSuccessHandler" />

    <security:logout logout-url="/user/logout"
        logout-success-url="/demo/user/logoutSuccess" />
</security:http>

<bean id="bCryptPasswordEncoder"
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider
        ref="authenticationProvider">
    </security:authentication-provider>
</security:authentication-manager>

Web服务的rest-security.xml:

<security:http create-session="stateless"
    entry-point-ref="digestEntryPoint">
    <security:intercept-url pattern="/provider/**"
        access="ROLE_WEBAPP" />

    <security:http-basic />
    <security:custom-filter ref="digestFilter"
        after="BASIC_AUTH_FILTER" />
</security:http>

<bean id="digestFilter"
    class="org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
    <property name="userDetailsService" ref="webappDetailsServiceImpl" />
    <property name="authenticationEntryPoint" ref="digestEntryPoint" />
</bean>

<bean id="digestEntryPoint"
    class="org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
    <property name="realmName" value="Contacts Realm via Digest Authentication" />
    <property name="key" value="acegi" />
</bean>

<security:authentication-manager>
    <security:authentication-provider
        ref="restAuthenticationProvider">
    </security:authentication-provider>
</security:authentication-manager>

有没有人有这种情况的经验?

3 个答案:

答案 0 :(得分:1)

我在这里找到了解决方案:https://blog.codecentric.de/en/2012/07/spring-security-two-security-realms-in-one-application/

这篇文章详细说明了我想要做的事情。

诀窍似乎是将pattern="/provider/**"添加到其余的http元素中。因此,正确的rest-security配置是:

<security:http create-session="stateless"
    entry-point-ref="digestEntryPoint" pattern="/provider/**"
    use-expressions="true">
    <security:intercept-url pattern="/provider/**"
        access="isAuthenticated()" />

    <security:http-basic />
    <security:custom-filter ref="digestFilter"
        after="BASIC_AUTH_FILTER" />
</security:http>

答案 1 :(得分:0)

这可能不是你想要的,但我会考虑将两个apis分开。一个用于人类,一个用于Web服务。

我们的人机界面就在根本上下文之外:

HTTP(S)://your.website.com / ...

然后,我们将Web服务接口从api上下文中删除:

HTTP(S)://your.website.com/api/v1 / ...

这使您可以轻松处理弹簧所需的两种不同类型的安全性。

答案 2 :(得分:0)

错误消息

  

通用匹配模式在过滤器链中的之前其他模式中定义,导致它们被忽略。

非常简洁。

您应该检查web.xml中contextConfigLocation上下文参数的bean定义文件的顺序。

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>security.xml,rest-security.xml</param-value>  
</context-param>

应重现上述错误消息。

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>rest-security.xml,security.xml</param-value>  
</context-param>

应该解决问题。