Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
590 views
in Technique[技术] by (71.8m points)

spring - PreAuthorize中的自定义方法不起作用“无法评估表达式'isAdmin()'”(Custom method in PreAuthorize is not working “Failed to evaluate expression 'isAdmin()'”)

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Autowired
    private ApplicationContext context;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new UserPermissionEvaluator());
        expressionHandler.setApplicationContext(context);
        return expressionHandler;
    }
}

And UserPermission class

(和UserPermission类)

@Component("UsrPermission")
public class UserPermissionEvaluator implements PermissionEvaluator {
    @Override
    public boolean hasPermission(Authentication authentication, Object targetObject, Object permission) {
        if (!targetObject.toString().equals("true") && targetObject.toString().equals(permission.toString())) {
            return true;
        } else if (!targetObject.toString().equals("true")) {
            return false;
        }
        ...
        return hasPermission;
    }

    public boolean isAdmin() {
        return CustomSecurityPrincipal.getSecurityPrincipal().isAdmin();
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
            Object permission) {
        return false;
    }

}

"hasPermission(x, y, z)" is working like charm.

(“ hasPermission(x,y,z)”的工作方式就像是魅力。)

But, I tried to create new custom method, and since it is registerd in MethodSecurityConfig.

(但是,由于它已在MethodSecurityConfig中注册,因此我尝试创建新的自定义方法。)

I am trying to call it directly

(我正在尝试直接调用它)

@PreAuthorize("isAdmin()")

Error:-

(错误:-)

org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method isAdmin() cannot be found on type org.springframework.security.access.expression.method.MethodSecurityExpressionRoot
    at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:225) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:134) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:94) ~
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:300) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:26) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:59) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:72) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:40) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at 

...

(...)

  ask by P Satish Patro translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In order to create a new custom expression, you need to create a custom implementation of MethodSecurityExpressionOperations and add a new operation to it.

(为了创建新的自定义表达式,您需要创建MethodSecurityExpressionOperations的自定义实现,并向其添加新的操作。)

Note that you can extend SecurityExpressionRoot to support default expressions:

(请注意,您可以扩展SecurityExpressionRoot以支持默认表达式:)

public class CustomMethodSecurityExpressionRoot
        extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

    private Object filterObject;
    private Object returnObject;
    private Object target;

    CustomMethodSecurityExpressionRoot(Authentication a) {
        super(a);
    }

    @Override
    public void setFilterObject(Object filterObject) {
        this.filterObject = filterObject;
    }

    @Override
    public Object getFilterObject() {
        return filterObject;
    }

    @Override
    public void setReturnObject(Object returnObject) {
        this.returnObject = returnObject;
    }

    @Override
    public Object getReturnObject() {
        return returnObject;
    }

    void setThis(Object target) {
        this.target = target;
    }

    @Override
    public Object getThis() {
        return target;
    }

    /**
     * Custom 'isAdmin()' expression
     */
    public boolean isAdmin() {
        // TODO: Add implement
        return true;
    }
}

Next, you need extend DefaultMethodSecurityExpressionHandler and make it to use CustomMethodSecurityExpressionRoot :

(接下来,您需要扩展DefaultMethodSecurityExpressionHandler并使其使用CustomMethodSecurityExpressionRoot :)

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
    @Override
    protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
        CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
        root.setPermissionEvaluator(getPermissionEvaluator());
        root.setTrustResolver(new AuthenticationTrustResolverImpl());
        root.setRoleHierarchy(getRoleHierarchy());
        return root;
    }
}

Finally, you should use CustomMethodSecurityExpressionHandler in the configuration:

(最后,您应该在配置中使用CustomMethodSecurityExpressionHandler :)

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new CustomMethodSecurityExpressionHandler();
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...