Shrio04 自定义Realm
1 说明
1.1 Realm的作用
Realm和认证和授权时的数据交互有关,相当于DAO层。
1.2 AuthorizingRealm
》层次关系图
》作用
继承AuthorizingRealm类后重写doGetAuthorizationInfo和doGetAuthenticationInfo就可以实现授权和认证逻辑。
2 代码实现
2.1 创建一个maven项目并引入shiro、junit依赖
2.2 创建一个类继承AuthorizingRealm
2.3 重写doGetAuthorizationInfo和doGetAuthenticationInfo
2.4 完整代码
package com.xunyji.demo04.realm; import com.xunyji.demo0.StringUtilsXyj;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set; /**
* @author AltEnter
* @create 2019-01-23 20:32
* @desc 自定义Realm,md
**/
public class CustomRealm extends AuthorizingRealm { private Logger log = LoggerFactory.getLogger(this.getClass()); private Map<String, String> userMap = new HashMap<String, String>(); {
getName();
// userMap.put("fury", "111111");
// userMap.put("fury", "96e79218965eb72c92a549dd5a330112");
userMap.put("fury", "66b747dd6c7c7c8ca4227a67fff8ea6e");
} /**
* 授权逻辑
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 01 获取用户名
String username = (String) principals.getPrimaryPrincipal();
// 02 获取权限集合
Set<String> permissionSet = getPermissionSetByUsername(username);
// 03 获取角色集合
Set<String> roleSet = getRoleSetByUsername(username);
// 04 封装SimpleAuthorizationInfo对象
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setRoles(roleSet);
simpleAuthorizationInfo.setStringPermissions(permissionSet);
return simpleAuthorizationInfo;
} /**
* 根据用户名获取权限集合
* @param username
* @return
*/
private Set<String> getPermissionSetByUsername(String username) {
HashSet<String> permissionSet = new HashSet<>();
permissionSet.add("user:create");
permissionSet.add("user:delete");
permissionSet.add("user:update");
return permissionSet;
} /**
* 根据用户名获取角色集合
* @param username
* @return
*/
private Set<String> getRoleSetByUsername(String username) {
HashSet<String> roleSet = new HashSet<>();
roleSet.add("admin");
roleSet.add("user");
return roleSet;
} /**
* 认证逻辑
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 01 获取前端用户名和密码
String username = (String) token.getPrincipal();
String passoword = new String((char[]) token.getCredentials());
if (StringUtilsXyj.isEmpty(passoword) || StringUtilsXyj.isEmpty(username)) {
String msg = "doGetAuthenticationInfo - 用户名和密码不能为空";
log.info(msg);
throw new RuntimeException(msg);
}
log.info(String.format("doGetAuthenticationInfo - 前端传过来的用户信息为 - 用户名为:%s ,用户密码为:%s", username, passoword));
System.out.println(String.format("doGetAuthenticationInfo - 前端传过来的用户信息为 - 用户名为:%s ,用户密码为:%s", username, passoword)); // 02 根据用户名获取用户密码
String pwd = getPasswordByUsername(username);
// 03 前端密码加密加盐处理
passoword = string2Md5Hash(passoword, "AltEnter");
System.out.println("加盐加密后的密码为:" + pwd); // 04 密码比对
if (passoword.equals(pwd)) {
// 封装SimpleAuthenticationInfo对象
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, passoword, getName());
// 加盐处理
simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("AltEnter"));
return simpleAuthenticationInfo;
} else {
String msg = "doGetAuthenticationInfo - 用户名或者密码错误";
log.info(msg);
System.out.println(msg);
throw new RuntimeException(msg);
}
} /**
* 密码加密加盐处理
* @param password 待加密密码
* @param salt 盐
* @return 经过加密和加盐处理后的密码
*/
private String string2Md5Hash(String password, String salt) {
return new Md5Hash(password, salt).toString();
} /**
* 根据用户名获取密码
* @param username
* @return
*/
private String getPasswordByUsername(String username) {
String pwd = userMap.get(username);
return pwd;
} public static void main(String[] args) {
// Md5Hash md5Hash = new Md5Hash("111111");
// System.out.println("111111加密后的结果为:" + md5Hash.toString());
// 96e79218965eb72c92a549dd5a330112 Md5Hash md5Hash = new Md5Hash("111111", "AltEnter");
System.out.println("111111经过MD5加密和AltEnter加盐后的结果为:" + md5Hash.toString());
// 66b747dd6c7c7c8ca4227a67fff8ea6e
}
}
3 测试类
package com.xunyji.demo04.realm; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test; import static org.junit.Assert.*; public class CustomRealmTest {
@Test
public void test01() {
CustomRealm customRealm = new CustomRealm();
// shiro加密 start
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//选择加密方式
matcher.setHashAlgorithmName("md5");
//加密次数
matcher.setHashIterations(1);
// 给自定义Realm设置加密规则
customRealm.setCredentialsMatcher(matcher);
// shiro加密 end // 更改认证策略 start
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
FirstSuccessfulStrategy firstSuccessfulStrategy = new FirstSuccessfulStrategy();
ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
modularRealmAuthenticator.setAuthenticationStrategy(firstSuccessfulStrategy);
defaultSecurityManager.setAuthenticator(modularRealmAuthenticator);
// 更改认证策略 end defaultSecurityManager.setRealm(customRealm); SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("fury", "111111"); subject.login(token);
System.out.println(String.format("认证信息为:%s", subject.isAuthenticated())); System.out.println(String.format("拥有admin角色吗? - %s", subject.hasRole("admin")));
System.out.println(String.format("拥有user:create权限吗? - %s", subject.isPermitted("user:create"))); subject.logout();
System.out.println(String.format("认证信息为:%s", subject.isAuthenticated())); }
}
4 注意
4.1 可以给SecurityManager设置认证策略

4.2 可以给Realm设置MD5加密

4.3 SecurityManager必须先设置认证策略再设置Realm

Shrio04 自定义Realm的更多相关文章
- 权限框架 - shiro 自定义realm
上篇文章中是使用的默认realm来实现的简单登录,这仅仅只是个demo,真正项目中使用肯定是需要连接数据库的 首先创建自定义realm文件,如下: 在shiro中注入自定义realm的完全限定类名: ...
- Shrio认证详解+自定义Realm
Authentication(身份认证)是Shiro权限控制的第一步,用来告诉系统你就是你. 在提交认证的时候,我们需要给系统提交两个信息: Principals:是一个表示用户的唯一属性,可以是用户 ...
- Shiro第二篇【介绍Shiro、认证流程、自定义realm、自定义realm支持md5】
什么是Shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi),是一个权限框架,它和sp ...
- shiro(二)自定义realm,模拟数据库查询验证
自定义一个realm类,实现realm接口 package com; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Re ...
- shiro自定义Realm
1.1 自定义Realm 上边的程序使用的是shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. ...
- Shiro入门 - 通过自定义Realm连数数据库进行授权
shiro-realm.ini [main] #自定义Realm myRealm=test.shiro.MyRealm #将myRealm设置到securityManager,相当于Spring中的注 ...
- Shiro入门 - 通过自定义Realm连数数据库进行认证(md5+salt形式)
shiro-realm-md5.ini [main] #定义凭证匹配器 credentialsMatcher=org.apache.shiro.authc.credential.HashedCrede ...
- Shiro入门 - 通过自定义Realm连数数据库进行认证
添加shiro-realm.ini文件 [main] #自定义Realm myRealm=test.shiro.MyRealm #将myRealm设置到securityManager,相当于Sprin ...
- shiro教程2(自定义Realm)
通过shiro教程1我们发现仅仅将数据源信息定义在ini文件中与我们实际开发环境有很大不兼容,所以我们希望能够自定义Realm. 自定义Realm的实现 创建自定义Realmjava类 创建一个jav ...
随机推荐
- Winform开发常用控件之ComboBox、ListBox
ComboBox就是我们常见的下拉框,对于此类控件,我们最关心的当然是数据的绑定和选择值得获取. 首先介绍个属性DropDownStyle,如果不允许ComboBox输入值,只能选择,就选DropDo ...
- 2018-2019-2 《网络对抗技术》Exp1 PC平台逆向破解 20165222
Exp1 PC平台逆向破解 1,掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码 NOP:空指令,作用就是直接跳到下一指令.机器码为:90. JNE:判断0标志位,不等于0跳转.机器码 ...
- C语言 scanf()和gets()函数的区别
C语言 scanf()和gets()函数的区别 1.相同点:scanf( )函数和gets( )函数都可用于输入字符串 2.不同点:两者在功能上有所区别,具体区别如下: 要实现如下需求“从控制台输入字 ...
- 获取 graphql schema 信息
模块 npm install -g get-graphql-schema get-graphql-schema GRAPHQL_URL > schema.graphql 简单使用 使用prism ...
- HDU1735 字数统计
版权声明:长风原创 https://blog.csdn.net/u012846486/article/details/28011667 字数统计 Time Limit: 1000/2000 MS (J ...
- Linux 解压zip need PK compat. v4.5 (can do v2.1)
p7z 当使用7zip压缩大于4G的文件后,在linux下解压时,出现下面的提示,无法解压: [root@localhost root]# unzip Wrestlemania20.zip Archi ...
- Log4j(3)--rootLogger根配置和appender输出类型配置
参考博客:http://blog.java1234.com/blog/articles/270.html 一.rootLogger根配置: Log4j 根配置语法 log4j.rootLogger = ...
- [html][javascript] Cookie
更多可参考:http://www.cnblogs.com/newsouls/archive/2012/11/12/2766567.html // 读 cookie 方法 function getCoo ...
- 5月31日上课笔记-Mysql简介
一.mysql 配置mysql环境变量 path中添加 D:\Program Files\MySQL\MySQL Server 5.7\bin cmd命令: 登录:mysql -uroot -p 退出 ...
- C# mysql 连接Apache Doris
前提: 安装mysql odbc驱动程序,目前只不支持8.0的最新版本驱动,个人使用的是5.1.12的驱动(不支持5.2以上版本),下载地址为: x64: https://cdn.mysql.com ...
