我们有一个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>
有没有人有这种情况的经验?
答案 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>
应该解决问题。