秋雨 De Blog

一个技术小白的个人博客

shiro框架多realm权限认证配置

我们做shiro框架经常会遇到这种情况,用户数量很多,又不在同一个表里,比如管理员一个表,用户一个表,商家一个表。这时我们就需要用到多realm来配置让他们用不同得realm来进行权限认证

跟登录认证一样,首先我们来说思路,因为权限认证的话肯定已经登录过了,那么我们就可以通过principals.getPrimaryPrincipal()获取当前登录的用户信息,然后对其进行判断看看他是哪个用户Bean的实体类以此来判断当前用哪个realm来认证

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

/*
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方法的写法

    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来验证权限

     @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内部以及配置文件相关在以往的文章中有详细说明

点赞

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注