Shiro系列 | 《Shiro开发详细教程》第二章:Shiro身份认证

本文目录:

► 第二章:Shiro身份认证

► 2.1 身份认证

► 2.2 环境准备

► 2.3 登录、退出

下节文章预告

► 第二章:Shiro身份认证(预告)

► 2.4 身份认证流程(预告)

2.1 身份认证

身份验证,即在应用中谁能证明他就是他本人。一般提供如他们的身份 ID 一些标识信息来表明他就是他本人,如提供身份证,用户名 / 密码来证明。

在Shiro中,用户需要提供principals (身份)和credentials(证明)给 shiro,从而应用能验证用户身份:

principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。一个主体可以有多个 principals,但只有一个 Primary principals,一般是用户名 / 密码 / 手机号。

credentials:证明 / 凭证,即只有主体知道的安全值,如密码 / 数字证书等。

另外两个相关的概念是之前提到的 SubjectRealm,分别是主体及验证主体的数据源。

最常见的 principals 和 credentials 组合就是用户名 / 密码了。

接下来先进行一个基本的身份认证。

2.2 环境准备

环境要求:Maven、IDEA

  • 新建Maven工程,并且导入以下Jar包依赖 (添加 junit、common-logging 及 shiro-core 依赖、log4j、slfj-api等即可):
<dependencies>
    <!--Shiro核心包-->
  <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.4.0</version>
  </dependency>
    <!--junit测试包-->
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
  <!--日志管理包-->
  <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
  </dependency>
  <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
  </dependency>
</dependencies>

2.3 登录、退出

  • 准备初始值数据到属性文件中(shiro.ini)
[users]
zhangsan=mima
sunwukong=mima

说明:使用 ini 配置文件,通过 [users] 指定了两个主体:zhang/ mima、sunwukong / mima.

  • 添加log4j的日志输出格式定义文件log4j.properties
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
# General Apache libraries
log4j.logger.org.apache=WARN
# Spring
log4j.logger.org.springframework=WARN
# Default Shiro logging
log4j.logger.org.apache.shiro=TRACE
# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
  • 增加测试类,测试主体信息(com.ms.ShiroTest)
  • 获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
  • 得到SecurityManager实例 并绑定给SecurityUtils
  • 得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
  • 登录,即身份验证
  • 身份验证成功与否具体信息
  • 退出

具体代码如下:

/**
 * @Auther: likang
 * @Description: shiro登录、退出功能演示
 */
public class ShiroTest {

    public static final Logger logger = LoggerFactory.getLogger(ShiroTest.class);

    public static void main(String[] args) {
        //1:获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //2:得到SecurityManager实例 并绑定给SecurityUtils
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        //3:得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        //4:登录,即身份验证
        if (!subject.isAuthenticated()){
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "mima2");
           try {
                subject.login(token);
                logger.info("登录成功");
            } catch (UnknownAccountException e) {
            //5:身份验证失败
                logger.info("用户名错误或者不存在");
            } catch (IncorrectCredentialsException e){
                logger.info("密码不匹配");
            } catch (LockedAccountException e){
                logger.info("用户已被锁定,请联系管理员");
            } catch (DisabledAccountException e){
                logger.info("用户已被禁用,请联系管理员");
            } catch (ExcessiveAttemptsException e){
                logger.info("用户登录次数过多");
            } catch (AuthenticationException  e){
                logger.info("用户登录失败,请联系管理员");
            }
        }
        subject.logout();//6:退出
    }
}

代码梳理:

  • 首先通过 new IniSecurityManagerFactory 并指定一个 ini 配置文件来创建一个 SecurityManager 工厂;
  • 接着获取 SecurityManager 并绑定到 SecurityUtils,这是一个全局设置,设置一次即可;
  • 通过 SecurityUtils 得到 Subject,其会自动绑定到当前线程;如果在 web 环境在请求结束时需要解除绑定;然后获取身份验证的 Token,如用户名 / 密码;
  • 调用 subject.login 方法进行登录,其会自动委托给 SecurityManager.login 方法进行登录;
  • 如果身份验证失败请捕获 AuthenticationException 或其子类,常见的如:

DisabledAccountException(禁用的帐号)、

LockedAccountException(锁定的帐号)、

UnknownAccountException(错误的帐号)、

ExcessiveAttemptsException(登录失败次数过多)、

IncorrectCredentialsException (错误的凭证)、

ExpiredCredentialsException(过期的凭证)等,

对于页面的错误消息展示,最好使用如 “用户名 / 密码错误” 而不是 “用户名错误”/“密码错误”,防止一些恶意用户非法扫描帐号库;

  • 最后可以调用 subject.logout 退出,其会自动委托给 SecurityManager.logout 方法退出。

从如上代码可总结出身份验证的步骤

  • 收集用户身份 / 凭证,即如用户名 / 密码;
  • 调用 Subject.login 进行登录,如果失败将得到相应的 AuthenticationException 异常,根据异常提示用户错误信息;否则登录成功;
  • 最后调用 Subject.logout 进行退出操作。

需要解决的问题?

  • 用户名 / 密码硬编码在 ini 配置文件,以后需要改成如数据库存储,且密码需要加密存储;
  • 用户身份 Token 可能不仅仅是用户名 / 密码,也可能还有其他的,如登录时允许用户名 / 邮箱 / 手机号同时登录。

可以留言欢迎讨论,如何解决这些问题,答案下期揭晓。

本文分享自微信公众号 - 码神联盟(lkchatspace)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏友弟技术工作室

lvm

逻辑卷管理LVM是一个多才多艺的硬盘系统工具。无论在Linux或者其他类似的系统,都是非常的好用。传统分区使用固定大小分区,重新调整大小十分麻烦。但是,LVM可...

44670
来自专栏LanceToBigData

linux(十二)之用户管理

前面学习了那么多关于linux的东西,相信大家都对linux应该 有一个大概的了解了。现在给大家分享的是linux中的用户管理,接下来让我们进入正题吧! 今天其...

22270
来自专栏JMCui

SpringBoot 之Actuator.

    Actuator 是 SpringBoot 项目中一个非常强大一个功能,有助于对应用程序进行监视和管理,通过 restful api 请求来监管、审计、...

14050
来自专栏耕耘实录

Linux下定时任务(系统任务调度、用户任务调度)crontab使用详解

版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢

19610
来自专栏hadoop学习笔记

Apache Shiro在web开发安全技术中的应用

前阶段就hadoop的分享了一些内容,希望对新手入门的朋友有点帮助吧!对于hadoop新手入门的,还是比较推荐大快搜索的DKHadoop发行版,三节点标准版还是...

16420
来自专栏Aox Lei

安装sentry

Sentry 是一个开源的实时错误报告工具,支持 web 前后端、移动应用以及游戏,支持 Python、OC、Java、Go、Node、Django、RoR 等...

54030
来自专栏散尽浮华

[原创]CI持续集成系统环境---部署gerrit环境完整记录

开发同事提议在线上部署一套gerrit代码审核环境,废话不多说,部署gerrit的操作记录如下: 提前安装好java环境,mysql环境,nginx环境 测试系...

42490
来自专栏信安之路

Linux 闯关游戏之通关秘籍

强盗战争是针对绝对的初学者。它将教授需要能够玩其他战争游戏的基础知识,通过这个游戏能学习到很多 Linux 的基础知识。和大多数其他游戏一样,这个游戏按层次组织...

60160
来自专栏hadoop学习

web开发安全框架中的Apache Shiro的应用

前阶段就hadoop的分享了一些内容,希望对新手入门的朋友有点帮助吧!对于hadoop新手入门的,还是比较推荐大快搜索的DKHadoop发行版,三节点标准版还是...

13860
来自专栏信安之路

【作者投稿】MITMF安装与使用

MITMF其实就是一个基于python编写的中间人攻击的框架,就好比metaspoit一样,无比强大且但十分易用。下面笔者就给大家介绍一下它有哪些用途,本文具有...

14100

扫码关注云+社区

领取腾讯云代金券