• Apache-Shiro自定义Realm实战


    自定义Realm简介 

      一般情况现自定义Realm是继承AuthorizingRealm。

      Realm的继承关系:AuthorizingRealm->AuthenticatingRealm->CachingRealm->Realm。

    步骤

    1. 创建一个类 ,继承AuthorizingRealm。
    2. 重写授权方法 doGetAuthorizationInfo。
    3. 重写认证方法 doGetAuthenticationInfo。

    重写方法介绍

    1. 当用户登陆的时候会调用 doGetAuthenticationInfo。
    2. 进行权限校验的时候会调用: doGetAuthorizationInfo。

    实体对象介绍 

    1. UsernamePasswordToken:对应就是 shiro的token中有Principal和Credential,继承关系UsernamePasswordToken-》HostAuthenticationToken-》AuthenticationToken
    2. SimpleAuthorizationInfo:代表用户角色权限信息
    3. SimpleAuthenticationInfo:代表该用户的认证信息

    代码实战

    自定义CustomRealm

    /**
     * @ClassName: CustomRealm
     * 自定义Realm
     * @Description:
     * @Author: Coding_wxb
     * @Date 2019.08.02 2:24
     */
    public class CustomRealm extends AuthorizingRealm {
        /**
         *模拟用户
         **/
        private final Map<String,String> userInfoMap = new HashMap<>();
        {
            userInfoMap.put("woxbwo","123");
            userInfoMap.put("zbbiex","456");
        }
        /**
         *模拟role -> permission
         **/
        private final Map<String, Set<String>> permissionMap = new HashMap<>();
        {
            Set<String> set1 = new HashSet<>();
            Set<String> set2 = new HashSet<>();
            set1.add("video:find");
            set1.add("video:buy");
            set2.add("video:add");
            set2.add("video:delete");
            permissionMap.put("woxbwo",set1);
            permissionMap.put("zbbiex",set2);
    
        }
        /**
         *模拟user -> role
         **/
        private final Map<String,Set<String>> roleMap = new HashMap<>();{
            Set<String> set1 = new HashSet<>();
            Set<String> set2 = new HashSet<>();
            set1.add("role1");
            set1.add("role2");
            set2.add("root");
            roleMap.put("woxbwo",set1);
            roleMap.put("zbbiex",set2);
    
        }
        /**
         *@description:
         * 该方法会在权限校验是调用
         *@params:  [principals]
         *@return:  org.apache.shiro.authz.AuthorizationInfo
         **/
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            System.out.println("权限 doGetAuthorizationInfo");
            String name = (String)principals.getPrimaryPrincipal();
            Set<String> permissions = getPermissionsByNameFromDB(name);
            Set<String> roles = getRolesByNameFromDB(name);
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.setRoles(roles);
            simpleAuthorizationInfo.setStringPermissions(permissions);
            return simpleAuthorizationInfo;
        }
        /**
         *@description:
         * 该方法会在用户身份认证时调用
         *@params:  [token]
         *@return:  org.apache.shiro.authc.AuthenticationInfo
         **/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("认证 doGetAuthenticationInfo");
            //从token获取身份信息,token代表用户输入的信息
            String name = (String)token.getPrincipal();
            //模拟从数据库中取密码
            String pwd = getPwdByUserNameFromDB(name);
            if(StringUtils.isEmpty(pwd)){
                return null;
            }
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, this.getName());
            return simpleAuthenticationInfo;
        }
        /**
         * 模拟从数据库获取用户角色集合
         * @param name
         * @return
         */
        private Set<String> getRolesByNameFromDB(String name) {
            return roleMap.get(name);
    
        }
    
        /**
         *  模拟从数据库获取权限集合
         * @param name
         * @return
         */
        private Set<String> getPermissionsByNameFromDB(String name) {
            return permissionMap.get(name);
        }
    
        /**
         *  模拟从数据库获取密码
         * @param name
         * @return
         */
        private String getPwdByUserNameFromDB(String name) {
            return userInfoMap.get(name);
        }
    }

     创建测试类

    /**
     * @ClassName: CustomRealmTest
     * @Description:
     * @Author: Coding_wxb
     * @Date 2019.08.02 2:50
     */
    public class CustomRealmTest {
        private CustomRealm customRealm = new CustomRealm();
        private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
    
        @Before
        public void init(){
            //构建环境
            defaultSecurityManager.setRealm(customRealm);
            SecurityUtils.setSecurityManager(defaultSecurityManager);
        }
    
        @Test
        public void testAuthentication() {
            //获取当前操作的主体
            Subject subject = SecurityUtils.getSubject();
            //用户输入的账号密码
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("woxbwo", "123");
            subject.login(usernamePasswordToken);
            //登录
            System.out.println("认证结果:"+subject.isAuthenticated());
    
            //拿到主体标示属性
            System.out.println("getPrincipal=" + subject.getPrincipal());
            subject.checkRole("role1");
            System.out.println("是否有对应的角色:"+subject.hasRole("role1"));
            System.out.println("是否有对应的权限:"+subject.isPermitted("video:add"));
    
        }
    }

    测试结果

    认证 doGetAuthenticationInfo
    认证结果:true
    getPrincipal=woxbwo
    权限 doGetAuthorizationInfo
    权限 doGetAuthorizationInfo
    是否有对应的角色:true
    权限 doGetAuthorizationInfo
    是否有对应的权限:false
  • 相关阅读:
    win11 千呼万唤 原生安卓体验及安装方法
    (转)pytorch和torch框架对比(区别 联系)
    AI深度学习部分框架了解
    有趣的USB接口和颜色分类
    后疫情时代读《浪潮之巅》第四版 读书笔记
    关于win11 VBS(基于虚拟化的安全性) 相关研究中
    Windows IPsec IP安全策略
    Element ui复杂表格(多级表头、尾行求合、单元格合并)前端导出excel
    es的常用字段类型和查询
    oom常见的解决方式
  • 原文地址:https://www.cnblogs.com/woxbwo/p/11286299.html
Copyright © 2020-2023  润新知