【Shiro安全框架 一】 十分钟带你熟悉Shiro的认证机制

2022年05月13日 阅读数:2
这篇文章主要向大家介绍【Shiro安全框架 一】 十分钟带你熟悉Shiro的认证机制,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

以前使用过shiro权限框架作过项目,可是一直没有机会系统 的了解一下shiro的认证机制
终于有机会好好研究一下这个轻量级安全框架🎄🎄🎁🎁java

Shiro的身份认证

【1】基本流程
请添加图片描述web

  • Shiro把用户的数据封装成标识token,token通常封装着用户名,密码等信息;
  • 使用Subject主体获取到封装着用户的数据的标识token;
  • Subject把标识token交给SecurityManager,在SecurityManager安全中心,SecurityManager把标识token委托给认证器Authenticator进行身份证。认证器的做用是通常用来指定如何验证,它规定本次认证用到那些Realm
  • 认证器Authenticator将传入的标识token,与数据源Realm对比,验证token是否合法

口说无凭,让咱们代码上见 📢📢
为了操做简便,在这里我就不使用数据库,开始操做:

数据库

代码实现阶段🐳🐳

业务层代码🎊🎊安全

public interface UserService {
   
   
    /**
     *  按照用户名查找密码
     * @param loginName
     * @return
     */
    String findPassWordByLoginName(String loginName);
}

//Service实现层
public class SecurityServiceImpl implements SecurityService {
   
   
    @Override
    public String findPassWordByLoginName(String loginName) {
   
   
        return "123";
    }
}

编写自定义CustomRealm 🎈🎈框架

public class CustomRealm extends AuthorizingRealm {
   
   

    /**
     * 受权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
   
   
        return null;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   
   
        //获取用户名
        String loginName = (String) token.getPrincipal();
        SecurityServiceImpl securityService = new SecurityServiceImpl();
        String password = securityService.findPassWordByLoginName(loginName);
        if ("".equals(password) || password == null){
   
   
            throw new UnknownAccountException("帐户不存在");
        }
        return new SimpleAuthenticationInfo(loginName,password,this.getName());
    }
}

##声明自定义的Relam
customRealm=com.pdx.shiro.realm.CustomRealm
securityManager.realms=$customRealm

编写测试类 🎏🎏ide

    @Test
    public void shiroLogin(){
   
   
        //导入权限的ini文件构建权限工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //工厂构建安全管理器
        SecurityManager instance = factory.getInstance();
        //使用SecurityUtils工具获取主体
        SecurityUtils.setSecurityManager(instance);
        Subject subject = SecurityUtils.getSubject();
        //构建帐号
        UsernamePasswordToken token = new UsernamePasswordToken("jay", "123");
        //登录操做
        subject.login(token);
        System.out.println("是否登录成功:"+subject.isAuthenticated());
    }

测试结果⌛️⌛️svg

在这里插入图片描述

虽然代码运行成功,一样也返回了预期的结果,可是它的过程是如何实现的呢?工具

源码追踪阶段(开启疯狂Debug模式)🔎🔎

【1】经过debug模式去进入subject.login(token)下的默认实现类中发现, 正如认证流程图中显示的同样,subject将用户的用户名密码委托给了SecurityManager去作。接着往下看🔎
在这里插入图片描述
【2】经过这个方法的注释能够看出SecurityManager又将用户的token委托给内部认证组件Authenticator去作。接着往下看🔎
在这里插入图片描述
【3】经过源码能够发现,其实SecurityManager的内部组件都是相互推脱,认证组件Authenticator又将传来的用户的token交给Realm去做比较。接着往下看🔎
在这里插入图片描述
在这里插入图片描述
【4】从图中能够看出,当前对象是Realm类对象,而即将调用的方法就是第二个红色框框中的doGetAuthenticationInfo(token)方法。当我看到这个方法的时候,总有一种似曾相识的感受,疯狂思考,是否是在哪里见过呀,忽然灵机乍现!!!猛拍大腿!这不就是咱们在自定义Realm中要重写的那个方法嘛!!!若是帐号密码经过了,那么返回一个认证成功的info凭证,若是认证失败,则抛出异常。接着往下看🔎
在这里插入图片描述
【5】接下来,就看到我自定义的Realm类了,此类继承了AuthorizingRealm,并实现了里面的doGetAuthenticationInfo()方法,在这个方法里就能够进行一系列数据库的操做,并将查询到的数据库中存放的用户名和密码封装成一个AuthenticationInfo对象返回。接着往下看🔎
在这里插入图片描述
【6】剩下的就很简单了,就是把输入的帐号密码和数据库中的帐号密码对比一下便可!若是没有报错,就说明这次登录操做成功了!!!
在这里插入图片描述测试