Ram*_*man 3 spring spring-mvc spring-security
您好我想制作一个拦截url模式并通过在spring security中使用sql查询动态访问.
通常我们在XML中使用这种表示法,我想从数据库中获取这些值(/ add-role和ROLE_ADMIN).
<intercept-url pattern="/add-role*" access="ROLE_ADMIN" />
Run Code Online (Sandbox Code Playgroud)
有可能动态地这样做吗?
Rob*_*nch 11
正如Spring Security FAQ所提到的,你应该做的第一件事是问我应该真的这样做吗?安全性很复杂,应该对配置进行广泛测试.允许配置动态更改只会使使应用程序更容易受到攻击的事情变得更加复杂.如果你真的想这样做,FAQ概述了实现这一目标的基本方法.我已经扩展了下面的FAQ的答案.
要动态获取安全URL映射,您可以实现自己的FilterInvocationSecurityMetadataSource.下面给出一个示例实现.
注意:请记住,将为Spring Security拦截的每个请求调用getAttributes,因此您很可能需要某种缓存.
public class JdbcFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
FilterInvocation fi = (FilterInvocation) object;
String url = fi.getRequestUrl();
HttpServletRequest request = fi.getHttpRequest();
// Instead of hard coding the roles lookup the roles from the database using the url and/or HttpServletRequest
// Do not forget to add caching of the lookup
String[] roles = new String[] { "ROLE_ADMIN", "ROLE_USER" };
return SecurityConfig.createList(roles);
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
Run Code Online (Sandbox Code Playgroud)
您无法使用命名空间来连接它,因此从FAQ中获取另一个提示您可以使用BeanPostProcessor,它可能如下所示:
public class FilterInvocationSecurityMetadataSourcePostProcessor implements BeanPostProcessor, InitializingBean {
private FilterInvocationSecurityMetadataSource securityMetadataSource;
public Object postProcessAfterInitialization(Object bean, String name) {
if (bean instanceof FilterSecurityInterceptor) {
((FilterSecurityInterceptor)bean).setSecurityMetadataSource(securityMetadataSource);
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String name) {
return bean;
}
public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(securityMetadataSource,"securityMetadataSource cannot be null");
}
}
Run Code Online (Sandbox Code Playgroud)
然后,假设上述两个bean都在包示例中,您将添加以下配置
<bean class="sample.FilterInvocationSecurityMetadataSourcePostProcessor">
<property name="securityMetadataSource">
<bean class="sample.JdbcFilterInvocationSecurityMetadataSource"/>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
如果你最终得到ClassCastException,你很可能会遇到在Spring Security 3.1.1+中修复的SEC-1957.请尝试更新到最新版本来解决这个问题.
| 归档时间: |
|
| 查看次数: |
8564 次 |
| 最近记录: |