在Spring Security中,可以指定多个<http>
配置,这些配置会导致多个SecurityFilterChains。我使用该功能来保护与普通Web应用程序不同的Rest API。 web app和rest api都是在不同的模块(maven artifacts)中开发的。在整个类路径(classpath*:/some-common-config-path/*.xml
)中通过通配符模式收集Spring配置。
web-security-config.xml
中的网络应用安全配置:
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cxf.apache.org/configuration/beans http://cxf.apache.org/schemas/configuration/cxf-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Security Config for web app -->
<http use-expressions="true" auto-config="false" entry-point-ref="loginEntryPoint">
...
</http>
<!-- Security Config for static resources -->
<http pattern="/static/**" security="none" />
...
</beans:beans>
api-security-config.xml
中的Rest API的安全配置:
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cxf.apache.org/configuration/beans http://cxf.apache.org/schemas/configuration/cxf-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<http pattern="/api/**" use-expressions="true" create-session="stateless"
authentication-manager-ref="apiAuthManager" entry-point-ref="restAuthenticationEntryPoint">
<intercept-url pattern="/api/**" access="hasRole('REST_API')" />
<http-basic />
</http>
...
</beans:beans>
问题是,类路径中两个模块的顺序是不可预测的,配置文件的解析顺序也是如此。在我的特定情况下,{/ 1>}在 api-security-config.xml
之后读取,并且应用程序上下文启动失败,并出现以下异常:
java.lang.IllegalArgumentException:通用匹配模式('/ **')在过滤器链中的其他模式之前定义,导致它们被忽略。请检查命名空间或FilterChainProxy bean配置中的排序
所以我要做的是以某种方式指定web-security-config.xml
元素的顺序,以便在最通用的元素之前解析特定的配置。有没有可能这样做?
答案 0 :(得分:4)
目前,没有办法打破Spring Security的XML配置并指定一个顺序,确保以正确的顺序加载XML。实现这一目标的一种方法是执行以下操作:
创建/some-common-config-path/security.xml配置,该配置由通用配置加载,该配置以正确的顺序导入两个配置(不在公共配置位置中):
<import resource="/not-common-config-path/api-security-config.xml"/>
<import resource="/not-common-config-path/web-security-config.xml"/>
您可以在带有Java配置的Spring Security 3.2中使用@Order注释执行此操作。正如所展示in the documentation:
@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
}
如果您愿意,也可以分解这些配置。
要自动选择Java配置,您可以轻松地将类路径扫描添加到您的设置中。例如,如果您使用的是以XML为中心的配置,并且所有Java配置都在com.example.config包中,则可以添加:
<!--
enable processing of annotations such as @Autowired and @Configuration
You may already have annotation-config
-->
<context:annotation-config/>
<!-- Add any Java Configuration -->
<context:component-scan base-package="com.example.config"/>
有关XML和Java配置的更多详细信息,请参阅从参考文献中组合Java and XML Configuration。