认证是用户来证明他们的身份。
subject认证主体,它包含有两个重要信息:
principals:身份,可以是用户名,邮件,手机号码等等,用来表示一个登陆主体身份
Creadentials:凭证,常见有密码,数字证书等。
shiro处理认证流程
第一步:调用Subject.login
方法
第二步:Security Manager负责验证,这是认证起始的地方。
第三步:Authenticator是真正的验证步骤
第四步:Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证
第五步:Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。
Realm:意思是域,Shiro从 Realm 中获取验证数据;
Realm 有很多种类,例如常见的jdbc realm,jndi realm,text realm。
实例演示
为了实现真实数据库验证,在数据库中创建一个数据库命名为db_shiro,创建表名字为users,固定写法否则会报错。
字段如下
1.创建一个maven项目,并在pom.xml文件中,并配置需要用到的jar包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.liy.shiro</groupId>
<artifactId>shiro01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shiro</name>
<description>shiro</description>
<dependencies>
<!-- shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<!-- slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
</dependencies>
</project>
这里需要数据源c3p0、MySQL的jdbc驱动、commons-logging以及shiro所需要的jar包
2.配置ini文件
命名为jdbc_realm.ini
[main]
#声明一个realm
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=""
#jdbcRealm的数据源设置信息
jdbcRealm.dataSource=$dataSource
#把jdbcRealm赋给securityManager
securityManager.realms=$jdbcRealm
格式:
1.变量名 = 全类名
2.变量名.属性 = 为属性赋值,会调用set方法
3.$变量名 引用之前的一个对象实例
3.java代码
package com.liy.shiro;
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 JdbcRealmTest {
public static void main(String[] args) {
//读取配置文件,初始化SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_realm.ini");
//获取SecurityManager实例
SecurityManager securityManager=factory.getInstance();
//把securityManager实例帮定到SecurityUtils中
SecurityUtils.setSecurityManager(securityManager);
//得到当前执行的用户
Subject currentUser=SecurityUtils.getSubject();
//创建token用户令牌
UsernamePasswordToken token = new UsernamePasswordToken("liy", "123");
try {
//身份认证
currentUser.login(token);
System.out.println("用户验证成功");
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("用户验证失败");
}
currentUser.logout();
}
}