Spring 安全性用于PrePostAnnotationSecurityMetadataSource
查找@PreAuthorize
Spring-EL 表达式并将其转换为ConfigAttribute
.
您可以实现您的MyAuthorizationCheckAnnotationSecurityMetadataSource
和覆盖getAttributes
方法来将您的枚举转换为 ConfigAttribute
;
像这样写你的代码:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAuthorizationCheck {
Application app();
AccessLevel level();
}
public class MyAuthorizationCheckAnnotationSecurityMetadataSource extends AbstractMethodSecurityMetadataSource {
private final PrePostInvocationAttributeFactory attributeFactory;
public MyAuthorizationCheckAnnotationSecurityMetadataSource(PrePostInvocationAttributeFactory attributeFactory) {
this.attributeFactory = attributeFactory;
}
@Override
public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return Collections.emptyList();
}
this.logger.trace(LogMessage.format("Looking for FddApi annotations for method '%s' on target class '%s'",
method.getName(), targetClass));
MyAuthorizationCheck myAuthorization = findAnnotation(method, targetClass, MyAuthorizationCheck.class);
if (myAuthorization == null) {
this.logger.trace("No expression annotations found");
return Collections.emptyList();
}
Application app = myAuthorization.app();
AccessLevel level = myAuthorization.level();
// build the Spring-EL expression from enums
String expr = "hasPermission('" + app.name() + "_" + level.name() + "')";
PreInvocationAttribute pre = this.attributeFactory.createPreInvocationAttribute(null, null, expr);
return CollUtil.newArrayList(pre);
}
// other method can copy from PrePostAnnotationSecurityMetadataSource
...
}
然后注册 MyAuthorizationCheckAnnotationSecurityMetadataSource。
我们的代码需要 PreInvocationAuthorizationAdviceVoter 来检查权限,所以需要启用 prePostEnabled
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(
getExpressionHandler());
return new MyAuthorizationCheckAnnotationSecurityMetadataSource(attributeFactory);
}
}
最后你可以像这样使用@MyAuthorizationCheck:
@MyAuthorizationCheck(app = Application.USER_MANAGEMENT, level = AccessLevel.EDIT)
public String editUSer(User user);