9_16 shiro 认证和授权原理

  1. 认证
    1. Subject 调用 login 方法,传入一个 UsernamePasswordToken(封装有账号密码)
    2. Subject 有一个 叫DelegatingSubject 的实现类,这个子类有一个 SecurityManager 类型的成员变量, DelegatingSubject 的 login 调用的就是 SecurityManager 的login方法
public void login(AuthenticationToken token) throws AuthenticationException {

     ……

        Subject subject = securityManager.login(this, token);

              //这一句就是调用 SecurityManager 的login 方法,把UsernamePasswordToken 传进去了

              ……
    1. SecurityManager 有一个 DefaultSecurityManager 实现类,DelegatingSubject 实际上调用的就是DefaultSecurityManager 的login 方法,传入的还是 UsernamePasswordToken
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {

        AuthenticationInfo info;

        try {

            info = authenticate(token);

       ……

}
    1. 关键就是这个authenticate方法,它调用的是AuthenticatingSecurityManager 这个类的 authenticate 方法,
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

        return this.authenticator.authenticate(token);

}
    1. 下边这个就是 AuthenticatingSecurityManager 的 authenticate 方法了,这个类有一个Authenticator 类型的成员变量,AuthenticatingSecurityManager类的 authenticate 方法调用的就是 authenticator的authenticate方法,把最开始的UsernamePasswordToken传了进去
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

        return this.authenticator.authenticate(token);

}
    1. Authenticator  有一个实现了类是 AbstractAuthenticator,调用的这个authenticate 方法实际上是调到了AbstractAuthenticator 的 authenticate 方法
public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

 ……

        log.trace("Authentication attempt received for token [{}]", token);

        AuthenticationInfo info;

        try {

            info = doAuthenticate(token);

       ……

}
    1. 那么实际上调用的就是 doAuthenticate 方法了,这个方法是 AbstractAuthenticator 的子类 ModularRealmAuthenticator 实现的,到了这里,调用关系才算是理清了。
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {

        assertRealmsConfigured();

        Collection<Realm> realms = getRealms();

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

            return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);

        } else {

            return doMultiRealmAuthentication(realms, authenticationToken);

        }

 }

这个 doAuthenticate 会去遍历所有的 Realm, 然后执行它们的认证方法。

 

 

  1. 认证
    1. 只要写一个类实现 AuthorizingRealm, 重写 doGetAuthorizationInfo 方法就可以了
    2. 入口就是 hasRole 方法, 它调用的就是Subject 的 hasRole 方法,它有一个实现类DelegatingSubject,具体的 hasRole 方法就是在DelegatingSubject实现的,这个方法的具体实现是
public boolean hasRole(String roleIdentifier){

         return this.hasPrincipals() && this.securityManager.hasRole(this.getPrincipals(), roleIdentifier);

}
    1. 它调用就是securityManager.hasRole,hasRole实际上是 Authorizer 接口的一个方法,它有一个实现类 AuthorizingRealm,具体的 securityManager.hasRole 是在 AuthorizingRealm 执行的
public boolean hasRole (PrincipalCollection principal, String roleIdentifier){

AuthorizationInfo info = this.getAuthorizationInfo(principal);

        return this.hasRole(roleIdentifier, info);

}
    1. 它其实调用的本类的getAuthorizationInfo 方法
protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {

            if (info == null) {

                info = this.doGetAuthorizationInfo(principals);

                if (info != null && cache != null) {

                    if (log.isTraceEnabled()) {

                        log.trace("Caching authorization info for principals:

……

        }

    }
    1. 这个方法关键的一句就是 doGetAuthorizationInfo, 这个方法是抽象的,恰恰就是我们重写的那个方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值