shiro是一个强大而且易用的安全框架(主要包括认证和授权),它比spring security更加简单,而且它不依赖于任何容器,可以和许多框架集成。

shiro的核心是安全管理器(SecurityManagement),它主要包括四个模块:

1.Authentication:认证模块,主要用于验证subject的身份和凭证,这里的subject包括但不仅限于用户。

2.Authorization:授权模块,主要用于将用户在数据库中对应的角色和权限查询出来并缓存起来供用户后续资源操作的权限判断使用;

3.Session management:会话管理器,管理subject请求会话;

4.cryptography:加密,主要是对凭证加密(单向的,这也正是subject忘记密码了只能创建新密码的原因)。

shiro还支持web,支持缓存机制,支持并发以及单元测试等等。

因为今天我就学了认证模块,所以今天先简单讲讲认证模块的实现。

实现步骤如下:

1.创建一个java项目;

2.导入shiro相关的jar包:

commons-beanutils-1.9.3.jar
commons-logging-1.2.jar
jcl-over-slf4j-1.7.12.jar
log4j-1.2.16.jar
shiro-all-1.4.1.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.6.4.jar

3.创建shiro的数据文件(这里用.ini文件来提供模拟数据库的数据)

4.编写代码流程

前两步我们这里省略,不会创建项目和导包的请自行百度0 0。

以下是测试用的shiro.ini文件:

[users]
zhangsan=

其中[users]是subject存储身份和凭证的目录,下面的zhangsan就是身份,而11111则是凭证或者说密码,这里我们给出的时具体的数据,但实际应用的数据应该是从数据库查询出来的,但我们这边就先这样简单测试。

接下来编写认证代码:

package test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class TestAuthencation {

//日志打印
private final static Logger logger = LoggerFactory.getLogger(TestAuthencation.class);
public static void main(String[] args) {
//1.创建securityManagement工厂(读取配置文件)
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.创建securityManagement实例
SecurityManager securityManager = factory.getInstance();
//3.将securityManagement设置进SecurityUtils中
SecurityUtils.setSecurityManager(securityManager);
//4.通过SecurityUtils获取subject实例
Subject subject = SecurityUtils.getSubject();
try {
//5.根据用户名和密码获取token
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "");
//6.调用subject.login()方法验证用户token
subject.login(token);
//7.判断是否验证登陆成功
if(subject.isAuthenticated()) {
System.out.println("登陆成功");
}
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
logger.error("用户名或者密码错误!");
} }
}

从上面代码可以看到shiro认证的完整流程,其中subject.login(token)这个方法的流程跳转非常复杂,但是最终在ModularRealmAuthenticator类中调用doAuthenticate(AuthenticationToken)这个方来进行认证,在这个方法中,会判断当前存在的realm数量,如果只有一个则直接将token与realm中查询出来的用户信息进行比对认证,如果是多个realm则通过Authentication Strategy(认证策略,后续学到具体的我会更新)来对token进行认证。当然我们也可以自定义realm,只需要创建一个新的realm类去继承AuthenticatingRealm或者AuthorizingRealm,然后实现认证和授权的方法即可编写自己的认证逻辑。

认证环节可能会发生异常,因此需要我们捕获异常并且打印异常日志,以便排查错误,这里常见的异常有上述代码中的AuthenticationException及它下面的子类异常如UnknowAccountException(用户名错误异常)和IncorrectCredentialsException(用户凭证错误异常)等等,这里需要注意,针对这些异常,我们需要进行模糊的提示,比如上面代码中的用户名或密码错误,而不能说当发生用户名错误异常时直接提示用户用户名异常,这样会让人明确知道错误的时用户名还是密码,会给一些不法人员有机可乘,虽然还有登陆尝试次数过多的异常,但是尽量避免输出明确的提示!

认证流程总结:

1.首先读取.ini文件获取安全管理器的工厂Factory;

2.然后通过工厂来生成SecurityManagement实例;

3.将安全管理器实例设置到SecurityUtils中去;

4.通过SecurityUtils生成Subject;

5.通过UsernamePasswordToken来生成用户令牌(通过传入用户身份和凭证);

6.调用subject.login(token)来对用户信息进行认证;

6.1.通过subject接口的实现类DelegatingSubject中的login方法,将token交给securityManager进行认证;

6.2.securityManager接口将认证过程交给它的实现类DefaultSecurityManager中,DefaultSecurityManager中的login方法又调用了AuthenticatingSecurityManager中的authenticate方法来进行认证;

6.3.AuthenticatingSecurityManager的authenticate方法中将认证过程交给了authenticator(认证器,终于到了认证器了。。。),最后认证器将这个token交由它的实现类ModularRealmAuthenticator去进行认证,具体是调用ModularRealmAuthenticator中的doAuthenticate(AuthenticationToken)方法来进行认证;

上述这几步可通过源码一步一步进行研究= =。

7.通过subject.isAuthenticated()方法来判断用户是否验证成功;

8.需要对验证部分进行异常捕获,并打印出合理的提示信息日志。

以上是今天我所学到的shiro的认证部分,等我学完授权模块我将会继续更新分享我的学习所得,大家有什么补充和分享的欢迎在评论区留言!

学习shiro第一天的更多相关文章

  1. 《跟我学Shiro》学习笔记 第一章:Shiro简介

    前言 现在在学习Shiro,参照着张开涛老师的博客进行学习,然后自己写博客记录一下学习中的知识点,一来可以加深理解,二来以后遗忘了可以查阅.没有学习过Shiro的小伙伴,也可以和我一起学习,大家共同进 ...

  2. 学习shiro第二天

    昨天讲了shiro的认证流程以及代码实现,今天将对这个进行扩展. 因为我们的测试数据是shiro.ini文件中配置的静态数据,但实际上数据应该从数据库中查询出来才合理,因此我们今天讲讲JdbcReal ...

  3. RabbitMQ学习总结 第一篇:理论篇

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  4. 学习KnockOut第一篇之Hello World

    学习KnockOut第一篇之Hello World 笔者刚开始学习KnockOut.写的内容就相当于一个学习笔记.且在此处向官网致敬,比较喜欢他们家的Live Example版块,里面有jsFiddl ...

  5. ActionBarSherlock学习笔记 第一篇——部署

    ActionBarSherlock学习笔记 第一篇--部署          ActionBarSherlock是JakeWharton编写的一个开源框架,使用这个框架,可以实现在所有的Android ...

  6. Java学习记录第一章

    学习Java第一章的记录,这一章主要记录的是Java的最基础部分的了解知识,了解Java的特性和开发环境还有Java语言的优缺点. 计算机语言的发展大概过程:机器语言--->汇编语言---> ...

  7. Shiro第一篇【Shiro的基础知识、回顾URL拦截】

    Shiro基础知识 在学习Shiro这个框架之前,首先我们要先了解Shiro需要的基础知识:权限管理 什么是权限管理? 只要有用户参与的系统一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安 ...

  8. [maven学习笔记]第一节,认识maven,搭建maven开发环境,写第一个HelloWorld

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/40142771 maven官网:http://maven.apache.org/ 学习视 ...

  9. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

随机推荐

  1. 剑指offer 17:合并两个有序链表

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则.   解题思路 链表基础操作考察,难点在于对于输入数据的把握,一定要考虑输入数据的全面性 1.出现 ...

  2. Linux--简单实现nfs的目录挂载,ntp时间同步

    一.NFS (Network FileSystem) 网络文件系统 是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源. 在NFS的应用中,本地NFS的客户端 ...

  3. Linux—添加开机启动(服务/脚本)

    系统启动时需要加载的配置文件 /etc/profile./root/.bash_profile/etc/bashrc./root/.bashrc/etc/profile.d/*.sh./etc/pro ...

  4. 2019CCPC网络选拔赛 hdu6703 array(主席树+set)

    题意 给你一个1~n的排列,由两种操作: 1 pos:将a[pos]+10 000 000 2 r k:求大于等于k且不等于a[1~r]的数的最小值. 强制在线. 思路 如果没有1操作,那么我们直接主 ...

  5. postman---postman简单介绍

    有小伙伴们想要了解postman,今天它来了,不要问它到底有多强大,自古免费好用即是王道,它不仅仅是开发接口强大的调试工具,还是测试接口的居家必备,它不仅仅可以把需要调用的接口保存下来方便调用,还可以 ...

  6. 爬虫---爬取b站小视频

    前面通过python爬虫爬取过图片,文字,今天我们一起爬取下b站的小视频,其实呢,测试过程中需要用到视频文件,找了几个网站下载,都需要会员什么的,直接写一篇爬虫爬取视频~~~ 分析b站小视频 1.进入 ...

  7. springmvc+strut2比较

    常见web框架中Struts2和SpringMVC独占鳌头,SpringMVC和Struts有什么不同? 我们可以从各个方面进行对比: 一:框架的思想设计上 SpringMVC控制器是基于方法上拦截, ...

  8. 手动O3

    #pragma GCC optimize(3,"Ofast","inline") 貌似这玩意并不能在noip考场上用

  9. Oracle SQL日期及日期格式获取命令

    日期及日期格式: 获取系统日期: sysdate() 格式化日期 to_char(sysdate(),'yyyy-mm-dd,hh24:mi:ss') to_date(sysdate(),'yyyy- ...

  10. 5. git-lab 项目操作

    项目操作 一.给成员授权项目权限 之前我们是给组增加成员.  当有的项目需要给组下面的成员授权不一样的时候. 我们需要在项目里面给成员授权权限 点击管理区域 点这个项目 看下图,我们可以看到  现在这 ...