Shiro授权-java版开发篇

引入依赖

<dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.3.1</version>
  </dependency>
  <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
  </dependency>
  <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
  </dependency>

开发方式

使用系统数据源开发

  • 开发数据源配置文件 shiro-permission.ini
[users]
libai=123456,role1,role2
zhangfei=123456,role2

[roles]
role1=user:create,user:update
role2=user:create,user:delete
role3=user:create,emp:create
  • 基于角色的授权
/**
 * 作用:基于角色的授权 Role-Based Access Control
 * 作者:gjx
 * 版本:V1.0
 * 
 */
public class TestRBACByRole {
    public static void main(String[] args) {
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        subject.login(new UsernamePasswordToken("libai","123456"));


        //用户授权检测
        //查询当前用户有没有这个角色
        boolean role1 = subject.hasRole("role3");
        System.out.println(role1);

        //查询当前用户是否有多个角色
        boolean[] booleans = subject.hasRoles(Arrays.asList("role1", "role2", "role3"));
        for (boolean aBoolean : booleans) {
            System.out.println(aBoolean);
        }

        //查询当前用户是否同时具有这些角色
        boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1", "role2", "role3"));
        System.out.println(hasAllRoles);

    }
}
  • 基于资源的授权
/**
 * 作用:基于资源的授权 Resource-Based Access Control
 * 作者:gjx
 * 版本:V1.0
 * 
 */
public class TestRBACByResources {

    public static void main(String[] args) {
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        //认证
        subject.login(new UsernamePasswordToken("libai","123456"));


        //用户授权检测
        //查询是否含有某个权限
        boolean permitted = subject.isPermitted("user:create");
        System.out.println(permitted);

        //查询当前用户是否同时含有多个权限
        boolean permittedAll = subject.isPermittedAll("user:create", "user:update");
        System.out.println(permittedAll);


    }
}

使用自定义数据源开发

  • 开发自定义数据源
/**
 * 作用: 自定义数据源
 * 作者:gjx
 * 版本:V1.0
 */
public class MyRealm extends AuthorizingRealm {
     /**
     * 获取授权信息 角色信息+权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        if("libai".equals(username)){
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRole("root");
            info.addRole("admin");
            info.addRole("user");

            info.addStringPermission("user:add");
            info.addStringPermission("user:query");
            info.addStringPermission("user:remove");
            return info;
        }
        return null;
    }

    /**
     * 获取认证信息方法
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("**********");
        UsernamePasswordToken usernamePasswordToken=  (UsernamePasswordToken)authenticationToken;
        String username = usernamePasswordToken.getUsername();

        if("libai".equals(username)){
            return new SimpleAuthenticationInfo("libai","3d53b73c485f523ef2fe45f2b8dd3c58",ByteSource.Util.bytes("ABCD"),UUID.randomUUID().toString());
        }

      return null;
    }
}
  • 开发数据源配置文件 shiro-md5Realm.ini
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#定义散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1024

#将凭证匹配器设置到realm中
myRealm=cn.gjxblog.demo3.CustomMD5Realm
myRealm.credentialsMatcher=$credentialsMatcher
#将realm设置到securityManager中
securityManager.realms=$myRealm
  • 开发程序
/**
 * 作用:基于资源的授权, Resource-Based Access Control
 * 作者:gjx
 * 版本:V1.0
 */
public class TestRBACByResources2 {
    public static void main(String[] args) {
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-md5Realm.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);

        Subject subject = SecurityUtils.getSubject();

        subject.login(new UsernamePasswordToken("libai","123456"));


        //用户授权检测
        //查询是否含有某个权限
        boolean permitted = subject.isPermitted("user:delete");
        System.out.println(permitted);

        //查询当前用户是否同时含有多个权限
        boolean permittedAll = subject.isPermittedAll("user:create", "user:update");
        System.out.println(permittedAll);
    }
}

总结

授权执行流程

1、执行subject.isPermitted(“user:create”)
2、securityManager通过ModularRealmAuthorizer进行授权
3、ModularRealmAuthorizer调用realm获取权限信息ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

权限字符串规则

权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

role1 = user:create role1 角色对用户资源有创建的权限
role1 = user:update:1 role1 角色对用户id为1的这个资源有修改权限

例子:
用户创建权限:user:create,或user:create:*
用户修改实例001的权限:user:update:001
用户实例001的所有权限:user:*:001

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值