【问题标题】:how to control the user authentication using spring mvc如何使用spring mvc控制用户身份验证
【发布时间】:2011-12-17 05:55:24
【问题描述】:

我正在使用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只能对user(user3,user4)进行操作。

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

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

department/update/1

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

如何控制?

【问题讨论】:

    标签: spring authentication spring-mvc


    【解决方案1】:

    一种选择是创建自定义 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"/>
    

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2014-02-04
      • 1970-01-01
      • 2016-05-18
      • 2020-07-05
      • 2012-08-24
      • 2019-07-27
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多