Shiro安全框架简介以及身份验证

Posted 锅锅7533

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shiro安全框架简介以及身份验证相关的知识,希望对你有一定的参考价值。

一、Shiro简介

官网  http://shiro.apache.org/download.html

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

三个核心组件:Subject, SecurityManager 和 Realms.
Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。
  Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
  SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
  Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
  从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。
  Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。
 
------来源百度百科
 
二、项目配置

1.创建一个Maven项目

2.下载shirojar包,因为是Maven管理的 所以添加下依赖,就从中央仓库将jar包下载到本地仓库了

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
    <dependency>
       <groupId>org.apache.shiro</groupId>
       <artifactId>shiro-core</artifactId>
       <version>1.2.4</version>
     </dependency>      
</dependencies>

这个我下的是1.2.4版本,最新版本1.4.0,不支持IniSecurityManagerFactory解析ini,显示构造函数过时 如下图

有个slf4j api 包,这个是一个api接口包,我们还要引入slf4j的实现包,否则会报警告

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <version>1.7.21</version>
       <scope>test</scope> 
    </dependency>

<scope>标签要删除 否则会报如下错误

3.在src/main/resources/目录下新建个shiro配置文件File,shiro.ini

建好后会弹出个记事本,关闭,不用记事本打开,右键选中openwith选TextEditor

[users]  //用户
Robin=123456  //用户名=密码
Tom=123

4.在src/main/resources/目录下加个log4j.properties日志文件

5.在src/main/java目录下建个包com.guo.shiro,包下新建个类HelloWorld.java

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;
public class HelloWorld {
    public static void main(String[] args) {
        // 读取配置文件,初始化SecurityManager工厂
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini");
        // 获取securityManager实例
        SecurityManager securityManager=factory.getInstance();
        // 把securityManager实例绑定到SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        // 得到当前执行的用户
        Subject currentUser=SecurityUtils.getSubject();
        // 创建token令牌,用户名/密码
        UsernamePasswordToken token=new UsernamePasswordToken("Robin", "123456");
        try{
            // 身份认证
            currentUser.login(token);    
            System.out.println("身份认证成功!");
        }catch(AuthenticationException e){
            e.printStackTrace();
            System.out.println("身份认证失败!");
        }
        // 退出
        currentUser.logout();
    }
    }

这个身份验证获取的用户名和密码 是配置文件shiro.ini中的,要获取和验证数据库中的用户名和密码,往下看

 

三、身份认证

1、Subject 认证主体

Subject 认证主体包含两个信息: Principals:身份,可以是用户名,邮件,手机号码等,用来标识一个登录主体身份; Credentials:凭证,常见有密码,数字证书等等;

2、身份认证流程

Subject认证主体调用login()方法,传给SecurityManager处理,SecurityManager里有个

Authenticator实例,有个AuthenticatoStrategy策略,要读取安全数据的话

涉及到Realm 来获取安全数据

3、Realm

Realm:意思是域,Shiro 从 Realm 中获取验证数据; Realm 有很多种类,例如常见的 jdbcrealm,jndirealm,text realm。

4.以JDBCReaml 为例

a、 新建个db_shiro 库,建个users表,添加用户名Robin,密码123456

b、在mvnrepori 查找C3P0 依赖代码 和commons-logging 阿帕奇的公共日志 依赖代码

还有mysql的驱动包 依赖代码 贴入pom

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
     <dependency>
       <groupId>c3p0</groupId>
       <artifactId>c3p0</artifactId>
       <version>0.9.1.2</version>
     </dependency>
     
     <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <version>1.2</version>
    </dependency>
    
   <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
   <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.38</version>
   </dependency>

c、新建个jdbc_reaml.ini配置JDBCReaml

 

[main]
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro
dataSource.user=root
dataSource.password=123456
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm 

dataSource=com.mchange.v2.c3p0.ComboPooledDataSource 是下图中的jar包

dataSource=com.mchange.v2.c3p0.ComboPooledDataSource

(相当于实例化一个ComboPooledDataSource的对象dataSource)

dataSource.driverClass=com.mysql.jdbc.Driver

(相当于对象dataSource调用ComboPooledDataSource类中的setdiverClass方法,将mysql驱动设置进去)

 

jdbcRealm.dataSource=$dataSource

(将dataSource=com.mchange.v2.c3p0.ComboPooledDataSource中的dataSource对象赋值给

jdbcRealm.dataSource,用$相当于将dataSource对象引用过去。jdbcRealm点后的这个dataSource是下图中的setDataSource方法参数

jdbcRealm放入securityManager中,securityManager可以放多个属性用逗号隔开。

d、下来package com.guo.shiro.HelloWorld.java中代码

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;
public class HelloWorld {
    public static void main(String[] args) {
        // 读取配置文件,初始化SecurityManager工厂
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:jdbc_reaml.ini");
        // 获取securityManager实例
        SecurityManager securityManager=factory.getInstance();
        // 把securityManager实例绑定到SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        // 得到当前执行的用户
        Subject currentUser=SecurityUtils.getSubject();
        // 创建token令牌,用户名/密码
        UsernamePasswordToken token=new UsernamePasswordToken("Robin", "123456");
        try{
            // 身份认证
            currentUser.login(token);    
            System.out.println("身份认证成功!");
        }catch(AuthenticationException e){
            e.printStackTrace();
            System.out.println("身份认证失败!");
        }
        // 退出
        currentUser.logout();
    }
    }

5、错误

建表名为users ,不能建为t_user会报错

 

以上是关于Shiro安全框架简介以及身份验证的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot安全管理--整合shiro

第一个Shiro程序

Shiro 学习笔记——shiro简介

erp权限验证框架Shiro

Shiro安全框架入门篇

Shiro安全框架学习01 -入门