(三)自定义Realm
一、Realm概念
- Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源
- org.apache.shiro.realm.Realm接口如下:
String getName(); //返回一个唯一的Realm名字
boolean supports(AuthenticationToken token); //判断此Realm是否支持此Token
AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException; //根据Token获取认证信息

引入依赖
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.shyroke.www</groupId> <artifactId>firstShiro</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>firstShiro Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <shiro.version>1.3.2</shiro.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.21</version> <scope>runtime</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> <scope>runtime</scope> </dependency> <!-- Shiro dependencies: --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version> </dependency> </dependencies> <build> <finalName>firstShiro</finalName> </build> </project>
自定义的realm MapRealm.java
package realms; import java.util.HashMap;
import java.util.Map;
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 MapRealm implements Realm {
/** * userMap变量:用于存放用户身份和凭证(用户名和密码) */
private static Map<String, String> userMap;
static {
userMap = new HashMap<String, String>();
userMap.put("user1", "value1");
userMap.put("user2", "value2");
} /** * 该Realm的名字 */
public String getName() {
return "mapRealm";
} /** * 该Realm支持的token类型 */
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
} public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName = token.getPrincipal().toString();
String passWord = new String((char[]) token.getCredentials());
if (!userMap.containsKey(userName))
throw new UnknownAccountException("用户名错误");
if (!passWord.equals(userMap.get(userName)))
throw new IncorrectCredentialsException("密码错误");
AuthenticationInfo info = new SimpleAuthenticationInfo(userName, passWord, getName());
return info;
}
}
shiro.ini
[main] mapRealm=realms.MapRealm securityManager.realms=$mapRealm [users] yhj=123 zs=456

测试类
package test; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject; public class TestMain {
public static void main(String[] args) {
SecurityManager securityManager = new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("user2", "value2");
try {
subject.login(token);
System.out.println(token.getUsername() + "\t" + new String((char[]) token.getPassword()));
} catch (UnknownAccountException e) {
System.out.println(e.getMessage());
} catch (IncorrectCredentialsException e) {
System.out.println(e.getMessage());
}
}
}
具体的流程大概是:当程序执行到subject.login(token)时候,执行自定义realm即MapRealm的boolean supports(AuthenticationToken token)方法,如果该Realm支持该token返回true,继续执行MapRealm的AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)方法,如果该Realm不支持该token返回false,抛出异常:ealm [realms.MapRealm@1cd072a9] does not support authentication token [org.apache.shiro.authc.UsernamePasswordToken - user2, rememberMe=false]
结果:

(三)自定义Realm的更多相关文章
- Shiro -- (三) 自定义Realm
简介: Realm:域,Shiro 从从 Realm 获取安全数据(如用户.角色.权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定 ...
- Shrio认证详解+自定义Realm
Authentication(身份认证)是Shiro权限控制的第一步,用来告诉系统你就是你. 在提交认证的时候,我们需要给系统提交两个信息: Principals:是一个表示用户的唯一属性,可以是用户 ...
- Shiro第二篇【介绍Shiro、认证流程、自定义realm、自定义realm支持md5】
什么是Shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi),是一个权限框架,它和sp ...
- shiro中自定义realm实现md5散列算法加密的模拟
shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...
- shiro授权及自定义realm授权(七)
1.授权流程
- shiro自定义realm支持MD5算法认证(六)
1.1 散列算法 通常需要对密码 进行散列,常用的有md5.sha, 对md5密码,如果知道散列后的值可以通过穷举算法,得到md5密码对应的明文. 建议对md5进行散列时加salt(盐),进行 ...
- shiro学习笔记_0400_自定义realm实现身份认证
自定义Realm实现身份认证 先来看下Realm的类继承关系: Realm接口有三个方法,最重要的是第三个方法: a) String getName():返回此realm的名字 b) boolean ...
- 【Shiro】Apache Shiro架构之自定义realm
[Shiro]Apache Shiro架构之身份认证(Authentication) [Shiro]Apache Shiro架构之权限认证(Authorization) [Shiro]Apache S ...
- Java-Shiro(五):Shiro Realm讲解(二)IniRealm的用法、JdbcRelam的用法、自定义Realm
引入 上一篇在讲解Realm简介时,介绍过Realm包含大概4类缺省的Realm,本章主要讲解: 1)IniRealm的用法: 2)JdbcRealm基于mysql 默认表及查询语句实现认证.授权 ...
随机推荐
- Dataeye计算任务架构
https://mp.weixin.qq.com/s/9Q5-oU3bPIBieScwzrawDg 资源消耗降低2/3,Flink在唯品会实时平台的应用(有彩蛋) 王新春 DBAplus社群 2018 ...
- How can I get a Netty server to reload a TLS certificate when it is renewed?
java - How can I get a Netty server to reload a TLS certificate when it is renewed? - Stack Overflow ...
- SWT界面刷新
参考文章: https://segmentfault.com/q/1010000002956350 在UI线程sleep等待,是不会刷新界面的. outPrint.setText("其他 ...
- mac kafka 环境搭建 以及PHP的kafka扩展
1.kafka安装 brew install kafka 安装会依赖zookeeper. 注意:安装目录:/usr/local/Cellar/kafka/0.10.2.0 2.安装的配置文件位置 /u ...
- Django路由分组
通过上次的学习,我们已经对Django有了简单的了解,现在来深入了解下~ 1. 路由系统 1.1 单一路由对应 a. urls url(r'^login/', views.login), # log ...
- 常用SQL50句
Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题 ...
- python基础之模块(一)
概述 模块,用一砣代码实现了某个功能的代码集合.一个功能可能由 N 个函数来组成,这些函数写到一个py文件中,那么这个Py文件就是传说中的模块. 模块可将代码归类,让你的代码看着条理清晰,当然还需要你 ...
- mysql逻辑备份mydumper
mydumper是一个针对MySQL的高性能多线程备份和恢复工具,它提供了并发备份功能,备份效率有很大提高. 安装mydumper yum安装 # rpm -ivh https://github. ...
- Mac 裁剪mp3
系统自带的QuickTime Player
- ADFS2016和ADFS代理的安装与配置
一,ADFS安装教程 教程链接(包含安装和配置两个步骤): https://www.virtuallyboring.com/how-to-setup-microsoft-active-director ...