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登录认证配置

相关推荐
binnnngo4 小时前
Spring Boot集成阿里云OSS:对象存储实战指南
数据库·spring boot·阿里云
程序猿ZhangSir4 小时前
Redis 和 MySQL双写一致性的更新策略有哪些?常见面试题深度解答。
java·数据库·spring boot·redis·mysql·缓存·mybatis
专业系统开发老赵5 小时前
实战 | 基于 SpringBoot + MyBatis-Plus + UniApp 构建家政派单系统:架构解析与性能优化
spring boot·uni-app·mybatis
HongXuan-Yuan7 小时前
Spring Boot框架
java·数据库·spring boot
loveking67 小时前
Springboot读取nacos配置
java·spring boot·后端
binnnngo8 小时前
Spring Boot 实战:MD5 密码加密应用全解析
java·spring boot·后端
Binge毕设9 小时前
基于Springboot的网上订餐系统 【源码】+【PPT】+【开题报告】+【论文】
java·spring boot·后端·mysql·mybatis·idea
工业互联网专业11 小时前
基于springboot+vue的凉州区助农惠农服务平台
java·vue.js·spring boot·毕业设计·源码·课程设计·助农惠农服务平台
hweiyu0011 小时前
【Java全栈进阶架构师实战:从设计模式到SpringCloudAlibaba,打造高可用系统】
java·spring boot·分布式·spring·spring cloud·设计模式
ronshi14 小时前
Spring Boot使用异步线程池
spring boot·线程池