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

相关推荐
Ramble_Naylor21 小时前
东方通(TongWeb)SpringBoot开发指导
java·spring boot
JacksonMx21 小时前
@Transactional 最佳实践
java·spring boot·spring·性能优化
智研数智工坊1 天前
SpringBoot4.0.6 + Security7.x + JWT 最新完整实战|无状态权限认证、统一异常处理、可直接落地
java·spring boot·spring security·jwt·权限认证
一 乐1 天前
汽车租赁|基于SprinBoot+vue的汽车租赁管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·汽车·论文·毕设·汽车租赁管理系统
夕除1 天前
实战--2
java·spring boot·spring
霸道流氓气质1 天前
SpringBoot中使用Spring AI框架集成本地Ollama实现AI快速对话完整示例
人工智能·spring boot·spring
codingPower1 天前
JAVA后端安全进阶:基于HMAC-SHA256+Nonce+Timestamp的API防重放攻击方案
java·开发语言·spring boot·安全
霸道流氓气质1 天前
Windows批处理脚本完整指南:可移植的交互式SpringBoot项目管理
windows·spring boot·后端
小张小张爱学习1 天前
Spring Boot 多线程并发入门教程:ThreadPoolTaskExecutor + CompletableFuture
java·spring boot·后端
摇滚侠1 天前
SpringBoot 内嵌 TongWeb 东方通替换 Tomcat
java·spring boot·spring