【发布时间】:2012-01-25 07:18:01
【问题描述】:
这个问题更多的是关于设计模式、依赖注入而不是 Spring Security 本身,我希望没有特定 Spring Security 知识的人能够理解这个问题。
在Introduction to Spring Security 3/3.1 中,为了验证当前用户是否有权对目标对象执行操作,Mike Wiesner 实现了PermissionEvaluator。在对目标对象执行操作之前,此 bean 与安全配置相关联并在方法注释上被调用。
目的是检查用户是否被授权对特定对象执行特定操作。他展示了以下代码(为了简洁,我想没有空检查):
public class MyPermissionEvaluator implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication auth, Object target, Object perm) {
if (target instanceof MyRequest) { //first class of target object...
MyRequest req = (MyRequest) target;
if (perm.equals("cancel")) { //action we wish to perform on the object
return auth.getName().equals(req.getEmployee());
} else if (perm.equals("list")) { //another action
return !hr.getEmployee().equals("rod") || auth.getName.equals("rod");
}
} else if (target instanceof ...) { //second class of target object...
...
}
throw new UnsupportedOperationException("hasPermission not supported");
}
}
他提到这种实现方式,只适用于小型应用程序,但在实践中,它应该拆分为多个方法或类。这正是我的想法:
- 在多模块应用程序中,多个模块可能不知道彼此
- 我们应该应用开闭原则(添加新模块时)
我的问题是,您将如何解决这个问题?
我的想法是为每个目标对象类设置一个全局权限评估器和一个权限评估器。
public interface TargetPermissionEvaluator extends PermissionEvaluator {
Class getTargetClass(); //so we know for which target class we can use it
}
public class MyGlobalPermissionEvaluator implements PermissionEvaluator {
@Autowired
private List<TargetPermissionEvaluator> evaluators;
@Override
public boolean hasPermission(Authentication auth, Object target, Object perm) {
for (MyEvaluator evaluator : evaluators) {
if (target instanceof evaluator.getTargetClass()) {
return evaluator.hasPermission(auth, target, perm);
}
}
throw new UnsupportedOperationException("hasPermission not supported");
}
}
评估者列表,将在 Spring XML 配置中定义。你怎么看?是一个好方法还是你有更好的想法?我错过了一些更合适的设计模式吗?
【问题讨论】:
标签: spring design-patterns dependency-injection spring-security