我希望使用自定义注释标记类中的方法,该注释将使用spring安全性来控制授权决策。例如:
@Role("ADMIN")
public void accessControlledMethod(){}
我理解这意味着我需要注册我的自定义注释“角色”,这样当ConfigAttributes
做出授权决定时,它可能会导致AccessDecisionManager
出现。但是,我不明白如何使用spring security注册我的自定义注释,以便识别它。
我在框架代码中看到了一个可能的解决方案。有一个名为SecuredAnnotationSecurityMetadataSource的类,其文档说“为自定义注释注入AnnotationMetadataExtractor”。如果这是首选方法,我不知道如何配置SecuredAnnotationSecurityMetadataSource或如何将AnnotationMetadataExtractor注入其中。
答案 0 :(得分:4)
您可以在配置中扩展GlobalMethodSecurityConfiguration
:
@EnableGlobalMethodSecurity
@Configuration
public class MyMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return SecuredAnnotationSecurityMetadataSource(...);
}
}
在xml中,你可以这样做:
<global-method-security metadata-source-ref="customMethodSecurityMetadataSource">
...
</global-method-security>
<bean id="customMethodSecurityMetadataSource" class="org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource">
...
</bean>
customMethodSecurityMetadataSource可以是MethodSecurityMetadataSource的任何实例
答案 1 :(得分:1)
这在Spring 5中不起作用,因为默认情况下默认禁用Bean覆盖。它仅在将spring.main.allow-bean-definition-overriding
属性设置为true
的情况下起作用。
如果有人知道如何在不启用bean覆盖的情况下向MethodSecurityMetadataSource
添加自定义GlobalMethodSecurityConfiguration
,这对于较新的Spring版本将很有帮助
答案 2 :(得分:0)
在Spring Boot中,您可以通过覆盖MethodSecurityMetadataSource
中的相应方法并添加/修改超类的值来添加自定义AccessDecisionVoter
和GlobalMethodSecurityConfiguration
。
@Configuration
@AutoConfigureAfter(SecurityConfiguration.class)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
public MethodSecurityMetadataSource methodSecurityMetadataSource() {
var source = (DelegatingMethodSecurityMetadataSource) super.methodSecurityMetadataSource();
source.getMethodSecurityMetadataSources().add(new FooSecurityMetadataSource());
return source;
}
@Override
protected AccessDecisionManager accessDecisionManager() {
var manager = (AffirmativeBased) super.accessDecisionManager();
manager.getDecisionVoters().add(new FooVoter());
return manager;
}
}