shiro授权管理

1、授权

  授权,即访问控制,控制谁能访问哪些资源主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。

2、关键对象

  授权可简单理解为who对what(which)进行How操作

  who,即主体(sbuject),主体需要访问系统中的资源。

  what,资源(resource),如菜单,页面,按钮,类方法,系统商品信息。

  how,权限/许可(permission),规定了主体对资源的操作许可,通过权限可知主体对那些资源有操作许可。crud权限

 

3、授权流程

授权的流程是基于用户合法的访问

 

 

 

4、授权方式

  基于角色的访问
if(subject.hasRole("admin")){ //操作什么资源 }
  基于资源的访问控制
if(subject.isPermission("user:update:01")){ //资源实例 //对01资源拥有修改权限 }
if(subject.isPermission("user:update:*")){ //对所有资源,拥有update权限 }
if(subject.isPermission("user:*:01")){ //资源实例 //对01资源拥有所有权限 }

5、授权字符串

  权限字符串的规则是:资源标识符:操作:资源实例标识符,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。 
用户创建权限:user:create,或user:create:*
用户修改实例001的权限:user:update:001
用户实例001的所有权限:user:*:001

6、shiro实现方式

编程式

Subject subject = SecurityUtils.getSubject(); 
if(subject.hasRole("admin")) {
    //有权限      
}else {
    //无权限  
}

标签式

@RequiresRoles("admin")
public void hello() {
   //有权限  
}

标签式

Jsp/GSp标签,在jsp/GSp页面通过相应的标签完成
<shiro:hasRole name="admin">
    <!--有权限-->
</shiro:hasRole>
注意:Thymeleaf中使用shiro需要额外集成!

7、授权案例

CustomerRealm授权域,添加授权角色、授权资源
package com.demo.grant;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
//授权领域
public class CustomerRealm extends AuthorizingRealm {
    //授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取主要身份
        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        System.out.println("primaryPrincipal = " + primaryPrincipal);
        //根据身份信息  用户名   获取当前用户的角色信息,以及权限信息   xiaochen admin  user
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //将模拟数据库中查询角色信息赋值给权限对象
        simpleAuthorizationInfo.addRole("admin");
        simpleAuthorizationInfo.addRole("user");
        //将数据库中查询权限信息赋值给权限对象
        //对用户下01实例具有所有权限   这是资源路径实例
        simpleAuthorizationInfo.addStringPermission("user:*:01");
        //对product下一切资源实例具有创建权限,*可以省略
        simpleAuthorizationInfo.addStringPermission("product:create");

        return simpleAuthorizationInfo;
    }

    //认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        if("zhangsan".equals(principal)){        //模拟数据库中已经md5加盐处理过的密码
            String password = "efe2cdcad63be25838e3847becd43df4";
            String salt = "x0*&p";   //需要这个解开密码
            return new SimpleAuthenticationInfo(principal,password, 
                                                ByteSource.Util.bytes(salt),this.getName());
        }
        return null;
    }

}

测试类

package com.demo.md5;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

public class TestAuthenticatorCusttomerRealm {
    public static void main(String[] args) {
        //创建securityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //IniRealm realm = new IniRealm("classpath:shiro.ini");
        //设置为自定义realm获取认证数据
        CustomerRealm customerRealm = new CustomerRealm();
        //设置md5加密
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");  //添加加密字符串
        credentialsMatcher.setHashIterations(1024);//设置散列次数   打乱顺序
        customerRealm.setCredentialsMatcher(credentialsMatcher); //MD5加密器//设置自定义realm
        defaultSecurityManager.setRealm(customerRealm);  //将自定义的realm设置到安全管理中
        //将安装工具类中设置默认安全管理器
        SecurityUtils.setSecurityManager(defaultSecurityManager);  //将安全管理设置到安全工具中
        //获取主体对象   
        Subject subject = SecurityUtils.getSubject();  
        //创建token令牌
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
        try {
            //subject对象 中方法  +加盐 +验证+权限操作 主体对象调用login方法
            subject.login(token);//用户登录,shiro会自动将token中的password在自定义realm中加上盐去处理
            System.out.println("登录成功~~");
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误!!");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密码错误!!!");
        }

    }
}

效果

登录成功~~
primaryPrincipal = zhangsan
true
primaryPrincipal = zhangsan
primaryPrincipal = zhangsan
这是用户=======false
primaryPrincipal = zhangsan
primaryPrincipal = zhangsan
primaryPrincipal = zhangsan
true
false
true
=====================================================
primaryPrincipal = zhangsan
权限资源判断=====true
primaryPrincipal = zhangsan
权限true
primaryPrincipal = zhangsan
primaryPrincipal = zhangsan
true
false
primaryPrincipal = zhangsan
primaryPrincipal = zhangsan
true

 

posted @ 2020-12-18 14:31  上天安排的最大嘛!  阅读(128)  评论(0编辑  收藏  举报