Sri*_*air 5 spring spring-security
我正在为 Spring 安全性编写自己的 PermissionEvaluator,我想做的事情之一就是找出它所保护的方法的名称。
例如,如果没有图片中的方法名称,我有类似的内容:
postAuthorize("hasPermission(returnObject,'read')")
Event getEvent(int evendId) {
...
}
Run Code Online (Sandbox Code Playgroud)
和
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
if(targetDomainObject instanceof Event) {
return hasPermission(authentication, targetDomainObject, permission);
}
return targetDomainObject == null;
}
Run Code Online (Sandbox Code Playgroud)
但我还需要方法名称“getEvent”可供 hasPermission 使用。我可以通过在 hasPermission 调用中手动传递它来完成此操作,如下所示:
@PostAuthorize("hasPermission(new com.example.AuthZObject(returnObject,'getEvent'),'read')")
Event getEvent(int eventId);
Run Code Online (Sandbox Code Playgroud)
但有没有更自动化的方法来做到这一点?
@Ralph 这里的想法非常正确。第一步是创建 MethodSecurityExpressionOperations 的自定义实现,该实现可以在其上存储 Method 并使用它来计算表达式。例如:
public class MyMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
private Object filterObject;
private Object returnObject;
private Object target;
private Method method;
public MyMethodSecurityExpressionRoot(Authentication a) {
super(a);
}
// allow the method to be set
public void setMethod(Method m) {
this.method = m;
}
// optionally expose the method to be accessed in expressions
public Method getMethod() {
return method;
}
// create a method that will perform the check with
// the method name transparently for you
public boolean hasMethodPermission(Object target, Object permission) {
boolean result = false;
// do your calculations using the method member variable
// i.e. method.getName() and the arguments passed in
// of course you could delegate to another object if you want
// i.e.
// return hasPermission(new com.example.AuthZObject(target,method.getName()),permission));
// or you could do the logic right here
return result;
}
// implement the interface and provide setters
public void setFilterObject(Object filterObject) {
this.filterObject = filterObject;
}
public Object getFilterObject() {
return filterObject;
}
public void setReturnObject(Object returnObject) {
this.returnObject = returnObject;
}
public Object getReturnObject() {
return returnObject;
}
public void setThis(Object target) {
this.target = target;
}
public Object getThis() {
return target;
}
}
Run Code Online (Sandbox Code Playgroud)
接下来扩展 DefaultMethodSecurityExpressionHandler 并使用自定义表达式根。
public class MySecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler{
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation){
MyMethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot(authentication);
root.setThis(invocation.getThis());
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(new AuthenticationTrustResolverImpl());
root.setRoleHierarchy(getRoleHierarchy());
root.setMethod(invocation.getMethod());
return root;
}
}
Run Code Online (Sandbox Code Playgroud)
配置 MySecurityExpressionHandler 后,您应该能够使用以下内容:
@PostAuthorize("hasMethodPermission(returnObject,'read')")
Event getEvent(int eventId);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1796 次 |
| 最近记录: |