【Shiro权限管理】三、身份认证流程

一、总体图

二、结合实际代码,源码看流程。

1、通过Shiro相关的API创建SecurityManager得到一个Subjetc主体。

 //1、获取SecurityManager工厂,此处使用(shiro.ini)初始化配置文件。
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

        //2、得到SecurityManager实例
        SecurityManager securityManager = factory.getInstance();

        //3、将SecurityManager设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);

        //4、通过SecurityUtils获取Subject主体
        Subject subject = SecurityUtils.getSubject();

2、封装用户的认证信息(用户、密码)

这里直接调用构造方法进行创建。

//5、假设登录的用户名 密码是Jame 123(表示用户登录时输入信息 shiro.ini相当于数据库存信息)
        UsernamePasswordToken token=new UsernamePasswordToken("James","123");

3、通过Subject.login(token) 进行用户认证

      Subjetc接收用户信息,Subject是一个接口,通过调用其实现类DelegatingSubject (idea下 Ctrl+H可调出实现类)将Token委托给SecurityManager接口来完成认证。

在DelegatingSubject中有一个login()方法,在此方法中Shiro将token交给了SecurityManager接口。

SecurityManager继承了Authenticator、Authorizer、SessionManager等父类,自己又有非常多的实现类。每一层实现类都是对SecurityManager功能的增强。

SecurityManager接口是通过其实现类DefaultSecurityManager中的来login方法来完成认证过程。

在login方法中AuthenticationInfo含有身份和凭证信息,然后通过authenticate方法调用AuthenticatingSecurityManage类中的authenticate(token),将token传入。

在AuthenticatingSecurityManager.class中的authenticate()认证器是由默认实现类ModularRealmAuthenticator.class来完成认证

ModularRealmAuthenticator.class 中doAuthenticate 获取Realms信息。

 protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        this.assertRealmsConfigured();
        Collection<Realm> realms = this.getRealms();
        return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(realms, authenticationToken);
    }

在doAuthenticate方法运用了三目表达式。如果是单个Realm,就会调用doSingleRealmAuthentication( )

如果是单Realm 直接将realm和token中的信息进行比较判断是否成功。

  protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
        if (!realm.supports(token)) {
            String msg = "Realm [" + realm + "] does not support authentication token [" + token + "].  Please ensure that the appropriate Realm implementation is " + "configured correctly or that the realm accepts AuthenticationTokens of this type.";
            throw new UnsupportedTokenException(msg);
        } else {
            AuthenticationInfo info = realm.getAuthenticationInfo(token);
            if (info == null) {
                String msg = "Realm [" + realm + "] was unable to find account data for the " + "submitted AuthenticationToken [" + token + "].";
                throw new UnknownAccountException(msg);
            } else {
                return info;
            }
        }
    }
  1. 如果多realm那么需要通过AuthenticationStrategy strategy 认证策略信息来完成对应的认证工作。如果认证失败会指定抛出异常信息。
  2. protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
            AuthenticationStrategy strategy = this.getAuthenticationStrategy();
            AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);
            if (log.isTraceEnabled()) {
                log.trace("Iterating through {} realms for PAM authentication", realms.size());
            }
    
            Iterator var5 = realms.iterator();
    
            while(var5.hasNext()) {
                Realm realm = (Realm)var5.next();
                aggregate = strategy.beforeAttempt(realm, token, aggregate);
                if (realm.supports(token)) {
                    log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);
                    AuthenticationInfo info = null;
                    Throwable t = null;
    
                    try {
                        info = realm.getAuthenticationInfo(token);
                    } catch (Throwable var11) {
                        t = var11;
                        if (log.isDebugEnabled()) {
                            String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
                            log.debug(msg, var11);
                        }
                    }
    
                    aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);
                } else {
                    log.debug("Realm [{}] does not support token {}.  Skipping realm.", realm, token);
                }
            }
    
            aggregate = strategy.afterAllAttempts(token, aggregate);
            return aggregate;
        }

    Shiro的认证过程至此结束。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真香号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值