zoukankan      html  css  js  c++  java
  • 三、Shiro授权开发

    Shiro 支持三种方式的授权:
    
    I、 编程式:通过写if/else 授权代码块完成:
    
    Subject subject =SecurityUtils.getSubject();
    
    if(subject.hasRole(“admin”)) {
    
    //有权限
    
    } else {
    
    //无权限
    
    }
    
    II、 注解式:通过在执行的Java方法上放置相应的注解完成:
    
    @RequiresRoles("admin")
    
    public void hello() {
    
    //有权限
    
    }
    
    III、 JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
    
    <shiro:hasRolename="admin">
    
    <!— 有权限—>
    
    </shiro:hasRole>
    
    此教程序授权测试使用第一种编程方式,实际与web系统集成使用后两种方式。
    

    权限标识符

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

    I、根据配置文件认证

    [users]
    zhang3=123123,normal
    li4=123456,super
    
    [roles]
    # normal 具有用户的所有权限
    
    normal=user:*
    super=product:*,user:*
    
    package com.baizhi.Authorrizer;/**
     * @Author:luoht
     * @Description:
     * @Date:Create in 20:50 2018/12/30
     */
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @program: DJ
     * @description:
     * @author: luoht
     * @create: 2018-12-30 20:50
     **/
    
    public class TestAuthorize {
        public static void main(String[] args) {
            //如果授权,就先认证
            IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro3.ini");
            SecurityManager instance = iniSecurityManagerFactory.getInstance();
            SecurityUtils.setSecurityManager(instance);
            Subject subject =   SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken("zhang3", "123123");
            try {
                subject.login(token);
            } catch (UnknownAccountException e) {
                System.out.println(("用户名错误"));
            } catch (IncorrectCredentialsException e){
                System.out.println("密码错误");
            }
    
            boolean authenticated = subject.isAuthenticated();
    
            if (authenticated){
                /**
                 * 认证成功之后
                 * 编程式授权
                 * 1. 基于角色
                 * 2. 基于资源
                 *
                 */
    
                /* 1.1 判断当前主体是否含有某种角色*/
                boolean hasRole = subject.hasRole("normal");
                System.out.println(hasRole);
                /* 1.2 判断当前主体是否具有某些角色*/
                List<String> strings = Arrays.asList("normal", "super");
                boolean[] booleans = subject.hasRoles(strings);
                for (boolean aBoolean : booleans) {
                    System.out.println(aBoolean);
                }
    
                /* 1.3 判断当前主主体是否同时具有某些角色*/
                boolean hasAllRoles = subject.hasAllRoles(strings);
                System.out.println(hasAllRoles);
    
                /* 2.1 判断当前主体是否具有某个权限*/
                boolean subjectPermitted = subject.isPermitted("user:create");
                System.out.println(subjectPermitted);
                /* 2.2 判断当前用户书否具有某些权限*/
    
                List<String> stringList = Arrays.asList("user:create", "product:delete");
                String[] strings1={"user:create", "product:delete"};
                boolean[] permitted = subject.isPermitted(strings1);
                for (boolean b : permitted) {
                    System.out.println(b);
                }
                boolean permittedAll = subject.isPermittedAll(strings1);
                System.out.println(permittedAll);
    
    
            }
    
        }
    }
      
    

    II、数据库认证

    自定义Realm:

    package com.baizhi.Authorrizer;/**
     * @Author:luoht
     * @Description:
     * @Date:Create in 22:30 2018/12/30
     */
    
    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;
    
    /**
     * @program: DJ
     * @description:
     * @author: luoht
     * @create: 2018-12-30 22:30
     **/
    
    public class MyRealm3 extends AuthorizingRealm {
         /* 授权 | Actually, I don't know what that fucking means*/
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
            /*通过用户查询角色*/
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.addRole("normal");
    
            /*通过角色查询权限*/
            return simpleAuthorizationInfo;
        }
    
        /* 认证*/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            String principal = (String) authenticationToken.getPrincipal();
            if (principal.equals("zhang3")){
                return new SimpleAuthenticationInfo("zhang3","b8cc2120cdf1554cf35603e08f7f5524", ByteSource.Util.bytes("1345"),this.getName());
            }
            return null;
        }
    }
     
    
    [main]
    # 声明凭证匹配器
    credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
    # 声明realm
    realm2= com.baizhi.Authorrizer.MyRealm3
    securityManager.realms=$realm2
    # 告知realm使用HashedCredentialsMatcher 为凭证匹配器
    realm2.credentialsMatcher=$credentialsMatcher
    # 告知安全管理器使用自定义
    securityManager.realms=$realm2
    
    # 告知Shiro算法的名称
    credentialsMatcher.hashAlgorithmName=md5
    credentialsMatcher.hashIterations=1024 
    

    III、授权执行流程

    1. 执行subject.isPermitted("user:create")
    2. securityManager通过ModularRealmAuthorizer进行授权
    3. ModularRealmAuthorizer调用realm获取权限信息

    ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

  • 相关阅读:
    Zuul
    熔断机制
    跨域问题
    过滤器
    从Ftp下载某一文件夹下的所有文件(三)
    java操作Ftp文件的一些方式(一)
    Java代码实现FTP单个文件下载(二)
    一些order
    Spring Boot
    利用dubbo服务对传统工程的改造
  • 原文地址:https://www.cnblogs.com/adrien/p/10227146.html
Copyright © 2011-2022 走看看