如何使用spring mvc控制用户身份验证

时间:2011-10-28 11:48:09

标签: spring authentication spring-mvc

我正在使用spring mvc3来构建用户管理器系统。

该系统具有以下模型:

Department
User

部门具有层次结构,例如:

Dep1
  SubDep1
  SubDep2
    Sub_sub_dep1
    xxxx

如果部门/用户已经过身份验证,可以添加/更新/删除部门/用户,但他只能在他的部门和子部门内进行这些操作。

例如,有三个部门(有用户):

Dep01(user1:{id:1}}
  Dep0101(user2:{id:2}
  Dep0102(user3:{id:3}
    Dep010201(user4:{id:4}

所以user1可以执行/ add / upate / delete所有用户(user1,user2,user3,user4)

虽然user3只能为用户(user3,user4)执行操作。

我可以控制user3无法在department/list页面中看到user1和user2。

但如果他像这样输入网址怎么样:

department/update/1

必须避免这种情况,因为user1(其id为1)不属于Dep0102或Dep010201。

如何控制这个?

1 个答案:

答案 0 :(得分:3)

一种选择是创建自定义Spring Security PermissionEvaluator并使用hasPermission(Authentication authentication, Object targetDomainObject, Object permission)方法实现自定义检查。

保护方法的签名最终看起来像这样:

@PreAuthorize("hasRole('ROLE_USER') and hasPermission(#_dept, 'deptAndSubs')")
public String methodToProtect(String _dept)throws Exception    {
        <custom code>;
    }

hasPermission表达式的第一个参数是用户想要修改的部门,第二个是权限。对我们来说,deptAndSubs权限表示只有当被修改的部门等于用户指定的部门或该部门的任何子部门时,用户才能执行该方法(其他权限是'deptOnly'和'subsOnly')。

在我们的应用程序中,我们有一个自定义的Spring Security UserDetails对象,其中包含用户部门代码,因此我们可以直接从Spring传递给方法的Authentication对象中获取登录用户的部门。以下是自定义评估者最终看起来像:

    public class CustomPermissionEvaluator implements PermissionEvaluator {
           @Override
           public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
            AppUser appUser = (AppUser)authentication.getPrincipal();
            if(permission instanceof String){
                if("deptAndSubs".equals(permission)){
                    return isTargetDeptInUserDeptTree((String)targetDomainObject, appUser.getDeptCode());
                }else if(.... other permission checks){}
            }
            return false;
        }

方法isTargetDeptInUserDeptTree是自定义代码,用于提取用户的部门树并验证目标部门是否在其中。

最后,您必须设置xml配置:

<global-method-security pre-post-annotations="enabled" >
    <expression-handler ref="expressionHandler"/>
</global-method-security>

<beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <beans:property name="permissionEvaluator" ref="customPermissionEvaluator"/>
</beans:bean>

<beans:bean id="customPermissionEvaluator" class="....CustomPermissionEvaluator"/>
祝你好运!