zoukankan      html  css  js  c++  java
  • (2)shiro角色资源权限

    一般在web系统权限设计中,一般分为三个维度,用户,角色,资源,一个用户可以拥有多个角色,比如说可以是老师,也可以是班主任,一个角色也可以拥有多个资源。

    比如老师同时拥有查看班级学生和批改作业的资源,如果一个用户有老师这个角色,那么就代表他拥有了查看班级学生和批改作业的两个资源权限。

    因为只判断角色颗粒度太粗,而根据资源权限则比较细。

    校验权限代码

    在classpath下新建shiro-role.ini文件,内容如下:

    代表有一个zhang的用户,拥有role1角色(如果有多个角色,后面用逗号继续隔开role1,role2)

    role1这个角色有两个资源,分别是user:create和user:update。

    [users]
    zhang=123456,role1
    [roles]
    role1=user:create,user:update

    测试代码:

            Factory<SecurityManager> factory =new IniSecurityManagerFactory("classpath:shiro-role.ini");
            //得到安全管理器
            SecurityManager securityManager = factory.getInstance();
            //将securityManager托管给SecurityUtils
            SecurityUtils.setSecurityManager(securityManager);
    
            Subject subject = SecurityUtils.getSubject();
    
            UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123456");
    
            try {
                subject.login(token);
            } catch (AuthenticationException e) {
                e.printStackTrace();
            }
            //是否已经认证
            System.out.println(subject.isAuthenticated());
    
            //校验是否有对应的权限和资源,如果没有则抛出对应的异常UnauthorizedException
            subject.checkRole("role1");
            subject.checkPermission("user:create");
            //退出
            subject.logout();

    过程没有遇到任何错误,执行到了最后,但是如果你check一个zhang不存在的role或者permission,则会报UnauthorizedException。

    身份和凭证

    在登陆中,用户需要提供principals(身份)和credentials(证明/凭证)提供给shiro来进行认证和授权。

    principals可以有多个身份,但是只能有一个Primary principals,一般是登录账号,比如手机号。

    credentials一般是密码。

    在UsernamePasswordToken的账户密码就对应着身份和凭证。

    subject.login()原理

    当执行subject.login的时候,实际调用的是securityManager所属的Authenticator(默认是ModularRealmAuthenticator)的doAuthenticate方法进行验证。

     

     他会根据当前设置了几个realm走不同的方法(后面介绍多个realms)

     最终走的realm对应的getAuthenticationInfo方法,判断用户账号密码是否正确,如果错误则抛出对应的异常。正确则返回一个AuthenticationInfo对象。(这里是SimpleAuthenticationInfo)

     所以后面我们自定义realms的时候就覆盖getAuthenticationInfo这个方法即可。

    subject.checkRole原理

    当用户调用subject.checkRole("role1")判断用户是否有对应的角色的时候,底层还是走的SecurityManager所属的Authorizer的checkRole方法。

    hasRole然后又走了下面的方法

    最后获取到了所有的realms,上篇文章说了java环境下使用了IniRealm,并且注入到了Authenticator(认证器)和Authorizer(授权器)的一个成员变量中。

    所以getRealms就可以直接获取到所有的realms

    因为IniRealms继承了AuthorizingRealm,而IniRealm没有实现hasRole方法,所以会走他的继承类AuthorizingRealm里面的hasRole来判断是否有权限。下面就是对应的方法。

    在初始化IniRealm的时候会读取所有用户所属的role和permission并封装到成员变量中,getAuthorizationInfo方法就是返回了一个AuthorizationInfo对象里面获取了zhang所属role和permission。

    所以我们自定义realm进行授权的时候就是覆盖了realm的getAuthorizationInfo方法,里面封装的role和permission都是从数据库查询出来的。

    最后进行checkRole就很容易看懂了。

    如果返回false,则Authorizer会抛出UnauthorizedException授权失败异常。

    github地址

    https://github.com/cmniefei/shiroparent

  • 相关阅读:
    数据库连接代码
    智能家居资源汇总
    android应用设计与实现相关资源汇总
    嵌入式设计应用资料汇总,不定时更新中……
    Zigbee相关资料大全,不断更新中……
    H.264视频编码资料汇总,不断更新……
    星网锐捷笔试
    华为 10第二题 成都 约瑟夫环
    2014华为校园招聘上机测试题目(华科提前批)
    2014年华为校招成渝地区上机试题
  • 原文地址:https://www.cnblogs.com/nfcm/p/9875657.html
Copyright © 2011-2022 走看看