shiro多realm抛出异常问题

简介: 使用Shiro作为安全框架时,为了方便我们可以把异常提出为公共模块,当使用多Realm时,需要特殊处理下,不然,异常时只会抛出一种。最近写项目时,就遇到了该问题,本身项目有一个登录系统,需要多加一个OAuth2的单点登录,服务端已经OK,需要在项目中对接一下该服务端;特此记录下
  • 既然是多Realm,我们需要在每个Realm中重写Support方法
//UserRealm 自身验证
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }
//SSO 单点登录验证
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2SsoAuthenticationToken;
    }
  • 自定义一个类继承 ModularRealmAuthenticator,并重写doMultiRealmAuthentication方法
/**
 * @author yafengliang@yeah.net
 * @Description
 * @date 2022-08-18 9:18
 */
public class MultiRealmAuthenticator extends ModularRealmAuthenticator {

    private static final Logger log = LoggerFactory.getLogger(ModularRealmAuthenticator.class);


    @Override
    protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {

        AuthenticationStrategy strategy = getAuthenticationStrategy();
        AuthenticationInfo authentication = strategy.beforeAllAttempts(realms, token);
        if (log.isTraceEnabled()) {
            log.trace("Iterating through {} realms for PAM authentication", realms.size());
        }
        AuthenticationException authenticationException = null;
        for (Realm realm : realms) {
            authentication = strategy.beforeAttempt(realm, token, authentication);
            if (realm.supports(token)) {
                log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);
                AuthenticationInfo info = null;
                try {
                    info = realm.getAuthenticationInfo(token);
                   //因为默认使用的是AtLeastOneSuccessfulStrategy(),有一个Realm成功就可以
                  authenticationException = null;
                } catch (AuthenticationException e) {
                    authenticationException = e;
                    if (log.isDebugEnabled()) {
                        String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
                        log.debug(msg, e);
                    }
                }
                authentication = strategy.afterAttempt(realm, token, info, authentication, authenticationException);
            } else {
                log.debug("Realm [{}] does not support token {}.  Skipping realm.", realm, token);
            }
        }
        if (authenticationException != null) {
            throw authenticationException;
        }
        authentication = strategy.afterAllAttempts(token, authentication);
        return authentication;

    }
}
  • 在shiro的配置类中注入自定义类
@Bean
    public AbstractAuthenticator authenticator(UserRealm userRealm, OAuth2Realm oAuth2Realm){
        ModularRealmAuthenticator authenticator = new MultiRealmAuthenticator();
        authenticator.setRealms(Arrays.asList(userRealm,oAuth2Realm));
        authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return authenticator;
    }
  • 在securityManager中加入多realm
    /**
     * 安全管理器
     */
    @Bean
    public SecurityManager securityManager(UserRealm userRealm, OAuth2Realm oAuth2Realm,AbstractAuthenticator authenticator) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        // securityManager.setRealm(userRealm);
        securityManager.setRealms(Arrays.asList(userRealm, oAuth2Realm));
        // 注入缓存管理器;
        securityManager.setCacheManager(getEhCacheManager());
        // session管理器
        securityManager.setSessionManager(sessionManager());
        //解决多realm的异常问题重点在此
        securityManager.setAuthenticator(authenticator);

        return securityManager;
    }
  • 再次运行解决

感谢 https://blog.csdn.net/qq_46416934/article/details/124021822
感谢 https://blog.csdn.net/m0_67403188/article/details/124019651

目录
相关文章
|
6月前
|
数据库 数据安全/隐私保护
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(四)-全面详解(学习总结---从入门到深化)
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(四)-全面详解(学习总结---从入门到深化)
132 1
|
6月前
|
数据库 数据安全/隐私保护
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(二)-全面详解(学习总结---从入门到深化)
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(二)-全面详解(学习总结---从入门到深化)
390 0
|
SQL 安全 测试技术
05 Shrio Realm
05 Shrio Realm
46 0
|
安全 Java 数据库连接
Shiro 中的 Realm
Shiro 中的 Realm
114 0
|
存储 缓存 安全
|
缓存 安全 Apache
2021年你还不会Shiro?----3.分析身份认证源码实现自定义Realm
我们已经知道无论我们是认证还是授权,数据的获取都是来源于Realm,Realm就相当于我们的datasource,在上一篇中我们使用的是用IniRealm来加载我们的配置文件shiro.ini,同时我们也说了ini只是临时解决方案,在实际的开发中是不可能把用户信息和权限信息放在ini文件中的,都是来源于数据库,那么系统提供的IniRealm就不能满足我们的需要了,我们就需要自定义Realm来实现真正的场景,事实上ini文件也只是apache为我们提供学习使用的策略,下面我们就来看下怎么自己定义一个Realm。
116 0
2021年你还不会Shiro?----3.分析身份认证源码实现自定义Realm
|
缓存 前端开发 程序员
Shiro实现多realm方案
前后端分离的背景下,在认证的实现中主要是两方面的内容,一个是用户登录获取到token,二是从请求头中拿到token并检验token的有效性和设置缓存。
Shiro实现多realm方案
|
程序员 数据库 数据安全/隐私保护
2021年你还不会Shiro?----5.使用Shiro实现授权功能
每个用户对系统的访问都会对应着身份认证,那么身份认证完了以后呢,自然就是对该用户进行授权,判断用户请求的资源是否拥有权限,或者从数据中获取该用户对应的角色,从而判断对应的资源,该用户是否可以访问。
93 0
|
网络安全 Apache 网络架构
Apache Shiro内置过滤器
shiro内置过滤器研究   anon org.apache.shiro.web.filter.authc.AnonymousFilter authc org.apache.shiro.
760 0
|
安全 Java 编译器
Springboot整合Shiro的错误记录:Could not autowire. There is more than one bean of ‘Realm
今天在学习springboot整合shiro,在学习到创建安全管理器的时候出现了如下的错误,刚开始百思不得其解?
440 0
Springboot整合Shiro的错误记录:Could not autowire. There is more than one bean of ‘Realm