一個simmilar問題有它一個解決方法。安全點信息保存在MethodSecurityMetadataSource
實現中(然後由MethodInterceptor
使用),因此我們必須創建額外的MethodSecurityMetadataSource
。正如春季論壇帖子中所提到的,xml切入點配置保存在MapBasedMethodSecurityMetadataSource
中,並由ProtectPointcutPostProcessor
進行處理。我們還需要一個ProtectPointcutPostProcessor
的實例。不幸的是這個類是最終的,包私人所以有2種選擇:
- 創建自己的類和複製/粘貼原來的全部內容(這是我做的)
- 更改類改性劑與反射和創建原始一個實例(沒有這樣做,所以不知道是否會工作的優良)
然後在您的環境中創建以下豆:
@Bean
public Map<String, List<ConfigAttribute>> protectPointcutMap() {
Map<String, List<ConfigAttribute>> map = new HashMap<>();
// all the necessary rules go here
map.put("execution(* your.package.service.*Service.*(..))", SecurityConfig.createList("ROLE_A", "ROLE_B"));
return map;
}
@Bean
public MethodSecurityMetadataSource mappedMethodSecurityMetadataSource() {
// the key is not to provide the above map here. this class will be populated later by ProtectPointcutPostProcessor
return new MapBasedMethodSecurityMetadataSource();
}
// it's either the original spring bean created with reflection or your own copy of it
@Bean
public ProtectPointcutPostProcessor pointcutProcessor() {
ProtectPointcutPostProcessor pointcutProcessor = new ProtectPointcutPostProcessor((MapBasedMethodSecurityMetadataSource) mappedMethodSecurityMetadataSource());
pointcutProcessor.setPointcutMap(protectPointcutMap());
return pointcutProcessor;
}
我們已經創建了必要的豆類,現在我們必須告訴spring使用它們。我假設你正在擴展GlobalMethodSecurityConfiguration
。默認情況下它會創建DelegatingMethodSecurityMetadataSource
,其中包含其他MethodSecurityMetadataSource
的列表。根據你想要什麼來實現,可以有以下選擇:
如果你想保留所有其他MethodSecurityMetadataSource
S(如藥粥解析@Secured
註釋),你可以在委託元數據源的擴展列表覆蓋下面的方法:
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return mappedMethodSecurityMetadataSource();
}
它會在列表中注入它的第一個地方,雖然這可能會導致一些問題。
如果你想保持其他來源,但希望你是最後一個在列表中,然後覆蓋下面的方法
:如果你想
@Override
public MethodSecurityMetadataSource methodSecurityMetadataSource() {
DelegatingMethodSecurityMetadataSource metadataSource = (DelegatingMethodSecurityMetadataSource) super.methodSecurityMetadataSource();
metadataSource.getMethodSecurityMetadataSources().add(mappedMethodSecurityMetadataSource());
return metadataSource;
}
您源是唯一一個(你不想使用@Secured
或任何其他註釋),那麼你可以重寫同樣的方法,只是用不同的內容
@Override
public MethodSecurityMetadataSource methodSecurityMetadataSource() {
return mappedMethodSecurityMetadataSource();
}
就是這樣!我希望這將有助於