shiro框架多realm权限认证配置

我们做shiro框架经常会遇到这种情况,用户数量很多,又不在同一个表里,比如管理员一个表,用户一个表,商家一个表。这时我们就需要用到多realm来配置让他们用不同得realm来进行权限认证 跟登录认证一样,首先我们来说思路,因为权限认证的话肯定已经登录过了,那么我们就可以通过principals.getPrimaryPrincipal() 获取当前登录的用户信息,然后对其进行判断看看他是哪个用户Bean的实体类以此来判断当前用哪个realm来认证

首先我们要写一个用于选择用哪个realm来认证的MyAuthorizer类继承ModularRealmAuthorizer类

java 复制代码
/*
MyAuthorizer类继承后重写其中的isPermitted(PrincipalCollection principals, String permission),
isPermitted(PrincipalCollection principals, Permission permission),
hasRole(PrincipalCollection principals, String roleIdentifier)
三个方法,其中isPermitted方法是用来验证权限,hasRole方法是用来验证角色的
 */
public class MyAuthorizer extends ModularRealmAuthorizer {
    /**
     * Returns <code>true</code> if any of the configured realms'
     * {@link #isPermitted(PrincipalCollection, String)} returns <code>true</code>,
     * <code>false</code> otherwise.
     *
     * @param principals
     * @param permission
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        return super.isPermitted(principals, permission);
    }
    /**
     * Returns <code>true</code> if any of the configured realms'
     * {@link #isPermitted(PrincipalCollection, Permission)} call returns <code>true</code>,
     * <code>false</code> otherwise.
     *
     * @param principals
     * @param permission
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, Permission permission) {
        return super.isPermitted(principals, permission);
    }
    /**
     * Returns <code>true</code> if any of the configured realms'
     * {@link #hasRole(PrincipalCollection, String)} call returns <code>true</code>,
     * <code>false</code> otherwise.
     *
     * @param principals
     * @param roleIdentifier
     */
    @Override
    public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
        return super.hasRole(principals, roleIdentifier);
    }
}

三个方法里得内容基本差不多,所以这里只提供hasRole方法的写法

java 复制代码
 public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
        //判断realm是否存在
        assertRealmsConfigured();
        //获取当前登录对象实例
        Object primaryPrincipal = principals.getPrimaryPrincipal();
        //getRealms()获取当前所有的Realm,遍历所有的realm
        Iterator iterator=getRealms().iterator();
        while (iterator.hasNext()){
            Realm realm=(Realm) iterator.next();
            //判断是否是一个realm
            if (!(realm instanceof Authorizer)) continue;
            //判断当前登录对象实例是否为管理员实例
            if (primaryPrincipal instanceof Administrators) {
                if (realm instanceof AdminRealm)
                    return ((AdminRealm) realm).hasRole(principals, roleIdentifier);
            }
            //判断当前登录对象实例是否为用户实例
            if (primaryPrincipal instanceof User) {
                if (realm instanceof UserRealm)
                    return ((UserRealm) realm).hasRole(principals, roleIdentifier);
            }
            //判断当前登录对象实例是否为商户实例
            if (primaryPrincipal instanceof Merchants) {
                if (realm instanceof MerchantsRealm)
                    return ((MerchantsRealm) realm).hasRole(principals, roleIdentifier);
            }
        }
        return false;
    }

至于isPermitted方法就是把其中的return ((UserRealm) realm).hasRole(principals, roleIdentifier); 换为return ((UserRealm) realm).isPermitted(principals, permission);

然后还是一样将这个东西放到shiro配置文件里,告诉shiro用这个东西来决定用哪个realm来验证权限

java 复制代码
     @Bean
     public org.apache.shiro.mgt.SecurityManager securityManager(){
        DefaultWebSecurityManager defaultSecurityManager=new DefaultWebSecurityManager();
        defaultSecurityManager.setAuthenticator(customizedModularRealmAuthenticator());
        //将三个realm放置shiro装配到shiro框架中
        List<Realm> realms=new ArrayList<>();
        realms.add(userRealm());
        realms.add(adminRealm());
        realms.add(merchantsRealm());
        defaultSecurityManager.setRealms(realms);
        //多realm授权配置
        CustomerAuthrizer customerAuthrizer=new CustomerAuthrizer();
        customerAuthrizer.setRealms(realms);
        defaultSecurityManager.setAuthorizer(customerAuthrizer);
        return defaultSecurityManager;
    }
    @Bean
    public AdminRealm adminRealm(){
        AdminRealm adminRealm=new AdminRealm();
        //将密码加密与验证装配到realm中
        adminRealm.setCredentialsMatcher(credentialsMatcher());
        return adminRealm;
    }
    @Bean
    public UserRealm userRealm(){
        UserRealm userRealm=new UserRealm ();
        //将密码加密与验证装配到realm中
        userRealm.setCredentialsMatcher(credentialsMatcher());
        return userRealm;
    }
    @Bean
    public MerchantsRealm merchantsRealm(){
        MerchantsRealm merchantsRealm=new MerchantsRealm();
        //将密码加密与验证装配到realm中
        merchantsRealm.setCredentialsMatcher(credentialsMatcher());
        return merchantsRealm;
    }

至此多realm权限认证配置完成,realm内部以及配置文件相关在以往的文章中有详细说明

有关realm登录认证请查看:shiro框架多realm登录认证配置

相关推荐
翱翔-蓝天6 小时前
为什么“看起来很规范”的后端项目反而臃肿且性能下降
spring boot
80530单词突击赢7 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
long3167 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
独断万古他化8 小时前
【SSM开发实战:博客系统】(三)核心业务功能开发与安全加密实现
spring boot·spring·mybatis·博客系统·加密
rannn_1118 小时前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
qq_12498707538 小时前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
倒流时光三十年8 小时前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
码农小卡拉9 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
Dragon Wu9 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
一 乐10 小时前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端