写点什么

SpringBoot 集成 Shiro,并使用多个 Realm

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:3051 字

    阅读完需:约 10 分钟

@Override


protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {


Token token = (Token) authenticationToken;


//判断是否有 Realm 装配


this.assertRealmsConfigured();


Collection<Realm> realms = getRealms();


//如果不唯一,分类进行


Collection<Realm> waitChooseRealms = new ArrayList<>();


for (Realm realm : realms) {


//遍历所有 Realm


//通过获取 Realm 的名字,比较 token 的信息,将想要执行的 Realm 放到新的 Realms 组合里面


if(realm.getName().contains(token.getLoginType())){


waitChooseRealms.add(realm);


}


}


//与源码一样,如果只有一个,就执行一个


if (realms.size() == 1){


return doSingleRealmAuthentication((Realm)waitChooseRealms.iterator().next(), token);


}


//与源码一样,如果有多个,就将整个 Realms 数组放进去


return doMultiRealmAuthentication(waitChooseRealms,token);


}


}


创建多个 Realm




我自定义的 ModularRealmAuthentic 是根据 Realm 的名字来进行区分的,所以,Realm 的名字最后不要出现相同的关键字符串,比如下面我要创一个 user、manager 和 merchant 的 Realm,那么就不可以出现 usermerchant 这样的 Realm。否则,即会进行 userRealm,也会进行 merchantRealm。

UserRealm

这是原有的


/**


  • @Author: Ember

  • @Date: 2021/4/26 17:36

  • @Description:


*/


public class MyDiyModularRealmAuthenticator extends ModularRealmAuthenticator {


@Override


protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {


Token token = (Token) authenticationToken;


//判断是否有 Realm 装配


this.assertRealmsConfigured();


Collection<Realm> realms = getRealms();


//如果不唯一,分类进行


Collection<Realm> waitChooseRealms = new ArrayList<>();


for (Realm realm : realms) {


if(realm.getName().contains(token.getLoginType())){


waitChooseRealms.add(realm);


}


}


if (realms.size() == 1){


return doSingleRealmAuthentication((Realm)waitChooseRealms.iterator().next(), token);


}


return doMultiRealmAuthentication(waitChooseRealms,token);


}


}

ManagerRealm 和 MerchantRealm

这两个 Realm 只做测试使用,所以就不详细做认证和授权操作了


/**


  • @Author: Ember

  • @Date: 2021/4/26 17:47

  • @Description:


*/


public class ManagerRealm extends AuthorizingRealm {


@Override


protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {


return null;


}


@Override


protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {


System.out.println("=======进入了 ManagerRealm=========");


return null;


}


}


/**


  • @Author: Ember

  • @Date: 2021/4/26 17:49

  • @Description:


*/


public class MerchantRealm extends AuthorizingRealm {


@Override


protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {


return null;


}


@Override


protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {


System.out.println("=========进入了 MerchantRealm===========");


return null;


}


}


配置 ShiroConfig




因为自定义了多个 Realm,还有 ModularRealmAuthentic,所以这些我们都要装配上


/**


  • @Author: Ember

  • @Date: 2021/4/2 18:05

  • @Description: ShiroConfig


*/


@Configuration


public class MyShiroConfig{


/**


  • ShiroFactoryBean 装配安全管理

  • @param defaultSecurityManager

  • @return


*/


@Bean


public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager){


ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();


//这里要让 ThredContext 对 defaultSecurityManager 绑定,否则会报错


ThreadContext.bind(defaultSecurityManager);


shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);


return shiroFilterFactoryBean;


}


/**


  • 安全管理装配 Realm

  • @param realm

  • @return


*/


@Bean


public DefaultSecurityManager defaultSecurityManager(


@Qualifier("myRealm") MyUserRealm realm,


@Qualifier("MerchantRealm") MerchantRealm merchantRealm,


@Qualifier("ManagerRealm") ManagerRealm managerRealm,


@Qualifier("authent


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


icator") MyDiyModularRealmAuthenticator authenticator){


//注意这里要是 DefaultWebSecurityManager,否则报错


DefaultSecurityManager securityManager = new DefaultWebSecurityManager();


securityManager.setAuthenticator(authenticator);


//装配上 Realm


Collection<Realm> realms = new ArrayList();


realms.add(realm);


realms.add(merchantRealm);


realms.add(managerRealm);


//securityManager.setRealm(realm);


// securityManager.setRealm(merchantRealm);


securityManager.setRealms(realms);


return securityManager;


}


/**


  • 自定义的 ModularRealmAuthenticator

  • @return


*/


@Bean(name = "authenticator")


public MyDiyModularRealmAuthenticator modularRealmAuthenticator(){


MyDiyModularRealmAuthenticator myDiyModularRealmAuthenticator = new MyDiyModularRealmAuthenticator();


myDiyModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());


return myDiyModularRealmAuthenticator;


}


/**


  • 自定义 Realm

  • @return


*/


@Bean(name = "MerchantRealm")


public MerchantRealm merchantRealm(){


MerchantRealm realm = new MerchantRealm();


//自定义校验匹配器


HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();


//设置加密算法为 md5


hashedCredentialsMatcher.setHashAlgorithmName("md5");


//设置加密算法的散列次数


hashedCredentialsMatcher.setHashIterations(1024);


//将自定义匹配添加进 Realm 中


realm.setCredentialsMatcher(hashedCredentialsMatcher);


//todo 设置缓存


return realm;


}


@Bean(name = "ManagerRealm")


public ManagerRealm managerRealm(){


ManagerRealm realm = new ManagerRealm();


//自定义校验匹配器


HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();


//设置加密算法为 md5


hashedCredentialsMatcher.setHashAlgorithmName("md5");


//设置加密算法的散列次数


hashedCredentialsMatcher.setHashIterations(1024);


//将自定义匹配添加进 Realm 中


realm.setCredentialsMatcher(hashedCredentialsMatcher);


//todo 设置缓存


return realm;


}


@Bean(name = "myRealm")


public MyUserRealm realm(){


MyUserRealm realm = new MyUserRealm();


//自定义校验匹配器


HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();


//设置加密算法为 md5


hashedCredentialsMatcher.setHashAlgorithmName("md5");


//设置加密算法的散列次数


hashedCredentialsMatcher.setHashIterations(1024);


//将自定义匹配添加进 Realm 中


realm.setCredentialsMatcher(hashedCredentialsMatcher);


//todo 设置缓存


return realm;


}


}


如果没有让 ThreadContext 绑定 securityManager,会报错,如下图



测试




用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
SpringBoot集成Shiro,并使用多个Realm