人们经常问如何将安全的url(secured URLs)和安全元数据(security metadata)属性之间的映射存储在数据库中,而不是在应用程序上下文中。
第一件事你应该问问自己,你是否真的需要这样做。如果一个应用程序需要安全,那么它还需要根据定义的策略对安全性进行彻底地测试。在投入生产环境之前,它可能需要审计和验收测试。一个有安全意识的组织应该意识到,通过允许在运行时改变一行或两行配置数据库来修改安全设置,他们勤奋的测试过程所带来的好处可能会立即消失。如果你已经考虑到了这一点(可能在应用程序中使用了多重安全层),那么Spring security允许你完全定制安全元数据的来源。如果你选择,你可以让它完全动态化。
方法和web安全都通过AbstractSecurityInterceptor的子类来?;ぃ珹bstractSecurityInterceptor配置了一个SecurityMetadataSource,它获取特定方法或过滤器调用(filter invocation)的元数据。对于web安全,拦截器类FilterSecurityInterceptor使用标记接口FilterInvocationSecurityMetadataSource。"secured object"类型是一个FilterInvocation。在一个in-memory map中使用默认的实现(在< http >命名空间和显式配置拦截器时,存储URL模式列表和相应的“配置属性”(ConfigAttribute的实例)列表)。
加载另一个源的数据,你必须使用一个显式声明的安全过滤器链(通常是Spring security的FilterChainProxy)以便定制FilterSecurityInterceptor bean。你不能使用名称空间。自由使用特定的FilterInvocation来加载数据,你必须实现FilterInvocationSecurityMetadataSource,一个非常基本的梗概会看起来像这样:
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
public List<ConfigAttribute> getAttributes(Object object) {
FilterInvocation fi = (FilterInvocation) object;
String url = fi.getRequestUrl();
String httpMethod = fi.getRequest().getMethod();
List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
//使用这个信息查找数据库并填充属性列表
return attributes;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
需要更多信息,看DefaultFilterInvocationSecurityMetadataSource的代码。
FilterInvocation对象包含HttpServletRequest,所以你可以获得URL或任何其他相关的信息,基于你的决定将返回属性列表所包含的内容。