SPeL @PreAuthorize.hasRole:无法使用内部枚举中定义的角色

问题描述 投票:0回答:1

尊敬的各位专家,

我正在使用 Spring Security 来访问控制我的 REST API。作为其中的一部分,我定义了一个包含我的角色的枚举。

        @Component("AppConstants")
    public class AppConstants {
        public enum Role {ADMIN, SUPER_ADMIN, USER};
//this class contains app level String constants and other enums
    
    }

我想在 PreAuthorize.hasRole 注释中使用此枚举来定义控制器中的访问控制。

@PreAuthorize("hasRole(@AppConstants.Role.ADMIN.name())")

但是,该表达式无法计算,但出现以下异常:

**java.lang.IllegalArgumentException: Failed to evaluate expression 'hasRole(@AppConstants.Role.ADMIN.name())'**
        at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:33)
        at org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager.check(PreAuthorizeAuthorizationManager.java:68)
        at org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager.check(PreAuthorizeAuthorizationManager.java:40)
        at org.springframework.security.config.annotation.method.configuration.DeferringObservationAuthorizationManager.check(DeferringObservationAuthorizationManager.java:47)
        at org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor.attemptAuthorization(AuthorizationManagerBeforeMethodInterceptor.java:252)
        at org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor.invoke(AuthorizationManagerBeforeMethodInterceptor.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:702)
        
**Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'Role' cannot be found on object of type 'com.mycode.utils.AppConstants' - maybe not public or not valid?**
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:222)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:105)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:93)
        at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:62)
        at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:92)
        at org.springframework.expression.spel.ast.MethodReference.getArguments(MethodReference.java:164)
        at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:94)
        at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:119)
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:309)
        at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30)
        ... 98 more

从“可能不公开或无效”中得到提示,我尝试为 Enum 的值提供公共 getter 方法,但这没有帮助。

我在这里缺少什么?

java spring-boot spring-security enums spring-el
1个回答
0
投票

要解决此问题,请在

AppConstants
中创建静态方法来获取角色名称,然后在
@PreAuthorize
注释中使用这些方法。

  1. 更新

    AppConstants
    课程:

    @Component("AppConstants")
    public class AppConstants {
    
        public enum Role {
            ADMIN, SUPER_ADMIN, USER
        }
    
        public static String getRoleAdmin() {
            return Role.ADMIN.name();
        }
    
        public static String getRoleSuperAdmin() {
            return Role.SUPER_ADMIN.name();
        }
    
        public static String getRoleUser() {
            return Role.USER.name();
        }
    }
    
  2. 使用

    @PreAuthorize
    中的静态方法:

    @PreAuthorize("hasRole(T(com.mycode.utils.AppConstants).getRoleAdmin())")
    public void yourMethod() {
        // method implementation
    }
    

它确保 SpEL 可以正确访问角色名称。

© www.soinside.com 2019 - 2024. All rights reserved.