2021-11-03 shiro-core shiro认证流程和Realm的基本架构

wuchangjian2021-11-03 17:43:01编程学习

2021SC@SDUSC

Shiro认证流程

package com.shiro.test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;

public class AuthenticationTest {

    SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();

    @Before
    public void addUser(){
        simpleAccountRealm.addAccount("Mark","123456","admin","user");
        simpleAccountRealm.addAccount("Sam","123456","admin");
        simpleAccountRealm.addAccount("Adam","123456","user");
    }

    public void testAuthentication(UsernamePasswordToken token){

        //1.构建securityManager环境
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(simpleAccountRealm);

        //2.主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

        try {
            subject.login(token);
            System.out.println(token.getUsername()+" isAuthenticated:"+subject.isAuthenticated());
            subject.checkRole("admin");
            subject.logout();
            System.out.println(token.getUsername()+" isAuthenticated:"+subject.isAuthenticated());
	        }catch (org.apache.shiro.authc.UnknownAccountException e){
	            System.out.println("用户名"+token.getUsername()+"不存在");
	        }catch (org.apache.shiro.authc.IncorrectCredentialsException e){
	            System.out.println("密码错误");
	        }catch (org.apache.shiro.authz.UnauthorizedException e){
	            System.out.println("用户权限不足");
        }

    }

    @Test
    public void testAuthentication(){
        UsernamePasswordToken token1 = new UsernamePasswordToken("Mark","123456");
        UsernamePasswordToken token2 = new UsernamePasswordToken("San","123456");
        UsernamePasswordToken token3 = new UsernamePasswordToken("Adam","123456");
        testAuthentication(token1);
        //用户名不存在,抛出异常
        testAuthentication(token2);
        //用户密码错误,抛出异常
        testAuthentication(token3);
    }

}

代码追踪debug

  1. subject.login(token);
    通过Debugger模式追踪源码subject.login(token)发现,首先是进入了Subject接口的默认实现类DelegatingSubject,接着调用了DelegatingSubject.login()

  2. DelegatingSubject.login(token);
    在这里插入图片描述
    DelegatingSubject.login(token)中,DelegatingSubject将认证任务交给了securityManager来完成,也就是securityManager.login(this,token), securityManagerDefaultSecurityManager的一个实例

  3. DefaultSecurityManager.login(this,token);
    在这里插入图片描述
    在这里插入图片描述
    DefaultSecurityManager又将token传递给authenticator.authenticate()

  4. authenticator.authenticate(token);
    在这里插入图片描述
    authenticatorauthenticate()方法中,authenticator又将token传递给doAuthenticate()
    在这里插入图片描述
    authenticatordoAuthenticate()方法中,authenticator又根据realms的size处理认证token,我们假设realms.size()==1,此时,authenticator调用了doSingleRealmAuthentication()来对token进行认证
    在这里插入图片描述
    doSingleRealmAuthentication()方法中,realm开始发挥它的认证作用了,即realm.supports(token)

Realm的基本架构

shiro提供了四个内置realm可以帮助用户进行认证与授权:SimpleAccountRealm, JdbcRealm, IniRealm
SimpleRealm的类实现框架
在这里插入图片描述

JdbcRealm的类实现框架
在这里插入图片描述
IniRealm的类实现框架
在这里插入图片描述
不难发现,这三个内置的realm都直接或间接继承了AuthorizingRealm
shiro将数据库中的数据,存放到realm对象中,shiro中的realm体系较为复杂,但主要shiro的主要目的就是:认证与授权。
在项目中,一般不会直接实现Realm接口,也不会直接继承shiro实现的IniRealm。大部分情况都需要我们创建直接继承于AuthorizingRealm自定义的realm。

public class CustomRealm extends AuthorizingRealm {

    @Override//强制重新授权方法,以后再说
    protected AuthorizationInfo doGetAuthorizationInfo(
                           PrincipalCollection principalCollection) {
        return null;
    }

    @Override//强制重写的认证方法
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 
throws AuthenticationException {
        return null;
    }
}

相关文章

ajax实现图片的回显功能

前端页面 给文件上传域绑定一个改变事件 <tr> <td c...

第4章 分支结构程序设计练习

13页:第一题   第6题:    第15题...

Salesforce应用程序版本切换注意事项

在 Lightning Experience 和 Salesforce Classic...

系统服务器选型

1、系统服务器分类 服务器分类是依据服务器综合性能,特别是所采用的一些服务...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。