gpt4 book ai didi

spring - PreAuthorize 中的自定义方法不起作用 "Failed to evaluate expression ' isAdmin( )'"

转载 作者:行者123 更新时间:2023-12-04 13:17:21 25 4
gpt4 key购买 nike

@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;
}
}

和 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)” 工作起来很有魅力。但是,我尝试创建新的自定义方法,因为它已在 MethodSecurityConfig 中注册。我想直接调用它

@PreAuthorize("isAdmin()")

错误:-

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

...

最佳答案

为了创建新的自定义表达式,您需要创建 MethodSecurityExpressionOperations 的自定义实现并向其添加新操作。请注意,您可以扩展 SecurityExpressionRoot 以支持默认表达式:

public class CustomMethodSecurityExpressionRoot
extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

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

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

@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: Implement
return true;
}
}

接下来,您需要扩展 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;
}
}

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

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

关于spring - PreAuthorize 中的自定义方法不起作用 "Failed to evaluate expression ' isAdmin( )'",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59122271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com