shiro 最主要的功能就是验证身份信息,而它的操作就是放在 realm 中进行的,realm (域)相当于 DataSource,下面通过一个简单的实例在说明~~
1、新建maven项目,引入需要的 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.java.shiro</groupId>
<artifactId>Shiro2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Shiro1</name>
<description>Shiro1</description>
<properties>
<junit.version>4.9</junit.version>
<slf4j.version>1.7.12</slf4j.version>
<shiroCore.version>1.2.2</shiroCore.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiroCore.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
</dependencies>
</project>
package com.java.shiro.realm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
public class MyRealm implements Realm{
/**
* 返回一个唯一的Realm名字
*/
@Override
public String getName() {
String clazz = this.getClass().getName();
int lastIndexNum = clazz.lastIndexOf(".");
String className = clazz.substring(lastIndexNum+1);
return className;
}
/**
* 判断此Realm是否支持此Token
*/
@Override
public boolean supports(AuthenticationToken token) {
//仅支持UsernamePasswordToken类型的Token
return token instanceof UsernamePasswordToken;
}
/**
* 验证 根据Token获取认证信息
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();//用户名
String password = new String((char[])token.getCredentials());//密码
if (!"java".equals(username)) {
throw new UnknownAccountException();//用户名错误
}
if (!"123".equals(password)) {
throw new IncorrectCredentialsException();//密码错误
}
//如果身份认证验证成功,返回一个AuthenticationInfo实现;
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationInfo;
}
}
3、shiro-realm.ini配置文件指定自定义 realm
#单个 realm 配置
#声明一个 realm
MyRealm=com.java.shiro.realm.MyRealm
#指定 securityManager 的 realm 实现
#通过 $name 引入之前的 realm 定义
securityManager.realms=$MyRealm
#多个 realm 配置
#MyRealm1=com.java.shiro.realm.MyRealm1
#MyRealm2=com.java.shiro.realm.MyRealm2
#指定 securityManager 的 realm 实现
#securityManager.realms=$MyRealm1,$MyRealm2
#securityManager会按照realms指定的顺序进行身份认证。
#此处我们使用显示指定顺序的方式指定了Realm的顺序,如果删除“securityManager.realms=$myRealm1,$myRealm2”,
#那么securityManager会按照realm声明的顺序进行使用(即无需设置realms属性,其会自动发现),
#当我们显示指定realm后,其他没有指定realm将被忽略,如“securityManager.realms=$myRealm1”,那么myRealm2不会被自动设置进去。
5、测试
package com.java.shiro.test;
import junit.framework.Assert;
import org.apache.shiro.SecurityUtils;
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.junit.Test;
public class TestShiro {
@Test
public void test(){
//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
//2、得到SecurityManager实例 并绑定给SecurityUtils
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("java", "123");
try {
//4、登录,即身份验证
subject.login(token);
System.out.println("登录成功!");
} catch (Exception e) {
//5、身份验证失败
System.out.println("登录失败!");
}
Assert.assertEquals(true, subject.isAuthenticated());//断言用户已经登录
//6、退出
subject.logout();
}
}
jdbcRealm 是 shiro 链接数据库的操作
pom.xml 中加入依赖
<!-- 数据库及依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>0.2.23</version>
</dependency>
配置文件 shiro-jdbc-realm.ini 配置数据源
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/db_shiro
dataSource.username=root
dataSource.password=root
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm
测试和上面一样,将初始化文件换成 shiro-jdbc-realm.ini 即可
到此结束啦~~