人們經常問如何將安全的url(secured URLs)和安全元數據(security metadata)屬性之間的映射存儲在數據庫中,而不是在應用程序上下文中。
第一件事你應該問問自己,你是否真的需要這樣做。如果一個應用程序需要安全,那么它還需要根據定義的策略對安全性進行徹底地測試。在投入生產環境之前,它可能需要審計和驗收測試。一個有安全意識的組織應該意識到,通過允許在運行時改變一行或兩行配置數據庫來修改安全設置,他們勤奮的測試過程所帶來的好處可能會立即消失。如果你已經考慮到了這一點(可能在應用程序中使用了多重安全層),那么Spring security允許你完全定制安全元數據的來源。如果你選擇,你可以讓它完全動態化。
方法和web安全都通過AbstractSecurityInterceptor的子類來保護,AbstractSecurityInterceptor配置了一個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或任何其他相關的信息,基于你的決定將返回屬性列表所包含的內容。