人們經(jīng)常問如何將安全的url(secured URLs)和安全元數(shù)據(jù)(security metadata)屬性之間的映射存儲在數(shù)據(jù)庫中,而不是在應(yīng)用程序上下文中。
第一件事你應(yīng)該問問自己,你是否真的需要這樣做。如果一個應(yīng)用程序需要安全,那么它還需要根據(jù)定義的策略對安全性進行徹底地測試。在投入生產(chǎn)環(huán)境之前,它可能需要審計和驗收測試。一個有安全意識的組織應(yīng)該意識到,通過允許在運行時改變一行或兩行配置數(shù)據(jù)庫來修改安全設(shè)置,他們勤奮的測試過程所帶來的好處可能會立即消失。如果你已經(jīng)考慮到了這一點(可能在應(yīng)用程序中使用了多重安全層),那么Spring security允許你完全定制安全元數(shù)據(jù)的來源。如果你選擇,你可以讓它完全動態(tài)化。
方法和web安全都通過AbstractSecurityInterceptor的子類來保護,AbstractSecurityInterceptor配置了一個SecurityMetadataSource,它獲取特定方法或過濾器調(diào)用(filter invocation)的元數(shù)據(jù)。對于web安全,攔截器類FilterSecurityInterceptor使用標(biāo)記接口FilterInvocationSecurityMetadataSource。"secured object"類型是一個FilterInvocation。在一個in-memory map中使用默認(rèn)的實現(xiàn)(在< http >命名空間和顯式配置攔截器時,存儲URL模式列表和相應(yīng)的“配置屬性”(ConfigAttribute的實例)列表)。
加載另一個源的數(shù)據(jù),你必須使用一個顯式聲明的安全過濾器鏈(通常是Spring security的FilterChainProxy)以便定制FilterSecurityInterceptor bean。你不能使用名稱空間。自由使用特定的FilterInvocation來加載數(shù)據(jù),你必須實現(xiàn)FilterInvocationSecurityMetadataSource,一個非?;镜墓8艜雌饋硐襁@樣:
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>();
//使用這個信息查找數(shù)據(jù)庫并填充屬性列表
return attributes;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
需要更多信息,看DefaultFilterInvocationSecurityMetadataSource的代碼。
FilterInvocation對象包含HttpServletRequest,所以你可以獲得URL或任何其他相關(guān)的信息,基于你的決定將返回屬性列表所包含的內(nèi)容。