Java环境下shiro的测试

1.导入依赖的核心jar包

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>

2.认证程序

2.1 构建users配置文件 xxx.ini doGetAuthenticationInfo方法从该配置文件中获取数据与token中比对

[users]
test=123456
lisi=123456

测试程序

public class TestShiro {
public static void main(String[] args) {
//获取安全管理器工厂
IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");
//获取安全管理器
SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
//set认证器
SecurityUtils.setSecurityManager(securityManager);
//subject发起认证,获取subject
Subject subject = SecurityUtils.getSubject();
AuthenticationToken authenticationToken = new UsernamePasswordToken("test","123456"); //认证失败会抛出异常 密码:CredentialsException 账户:UnknownAccountException
try {
subject.login(authenticationToken);
} catch (AuthenticationException e) {
e.printStackTrace();
} //当前subject是否认证通过
boolean authenticated = subject.isAuthenticated();
System.out.println(authenticated);
}
}

认证流程:

token携带身份和凭证信息--->subject发起认证--->SimpleAccountRealm(doGetAuthenticationInfo)获取配置文件中的用户信息---->CredentialsMatcher接口的实现类SimpleCredentialsMatcher:doCredentialsMatch方法对配置文件中的信息与token携带的信息进行比对--->认证成功或者失败。

3.Shiro框架中的关键对象:

AuthenticatingRealm  //抽象类
//3.关键属性 该属性为凭证匹配器
CredentialsMatcher credentialsMatcher;
//1.该方法为抽象方法 其作用使用来获取数据
protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;
SimpleAccountRealm
//2.实现了AuthenticatingRealm抽象方法,用来获取配置文件中的用户信息,该类不做数据比对
SimpleCredentialsMatcher
//4.shiro中默认的凭证匹配器
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
Object tokenCredentials = this.getCredentials(token);
Object accountCredentials = this.getCredentials(info);
return this.equals(tokenCredentials, accountCredentials);
}

必须要知道的类与接口,不然很难理解自定义Realm时属性为什么设置,使用哪种实现类方法等等:

以下代码或者截图贴出最重要的地方.

类继承关系

AuthenticatingRealm类

abstract class AuthenticatingRealm{
//凭证匹配器 接口,其实现类做数据比对
private CredentialsMatcher credentialsMatcher;
//获取配置文件中的用户信息
protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;
}

该抽象方法返回类型AuthenticationInfo接口:

AuthorizingRealm类 抽象方法后面测试授权时使用

abstract class AuthorizingRealm{
//
//该抽象方法 获取数据 获取授权的数据
protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection var1);
}

该抽象方法返回类型AuthorizationInfo接口:

CredentialsMatcher凭证匹配器接口:

其中:SimpleCredentialsMatcher是shiro中默认的凭证匹配器,其子类Hashxxx等都是做加密认证时使用

4.开发自定义Realm

public class MyRealm extends AuthenticatingRealm {
//实现抽象方法doGetAuthenticationInfo
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
String principal =(String) authenticationToken.getPrincipal();
//查库取回User对象
SqlSession sqlSession = null;
try {
sqlSession = MySqlSession.getSqlSession();
} catch (IOException e) {
e.printStackTrace();
}
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserByUserName(principal);
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal,user.getPassword(),this.getName());
return authenticationInfo;
}
}

4.1通知shiro使用自定义realm

[main]
#自定义 realm
customRealm=com.nyist.test.MyRealm
#将realm设置到securityManager
securityManager.realms=$customRealm

注意:需要导入一个jar

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>

5.shiro的加密认证方式

5.1.使用shiro提供的Md5Hash类为一个字符串加密进行测试

public class TestMD5 {
public static void main(String[] args) {
Md5Hash hash = new Md5Hash("123456","salt",1024);
String s = hash.toHex();
System.out.println(s);
//a18d2133f593d7b0e3ed488560404083
}
}

5.2.修改配置文件,加入凭证匹配器的相关配置

[main]
#自定义凭证匹配器
hashedCredentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#凭证匹配器通知AuthenticatingRealm,由于自定义realm继承了AuthenticatingRealm,直接设置已有的MyRealm属性即可 #自定义 realm
customRealm=com.nyist.test.MyRealm
customRealm.credentialsMatcher=$hashedCredentialsMatcher
hashedCredentialsMatcher.hashAlgorithmName=MD5
hashedCredentialsMatcher.hashIterations=1024 #将realm设置到securityManager .realms使用set方式赋值
securityManager.realms=$customRealm

坑:Caused by: java.lang.IllegalStateException: Required 'hashAlgorithmName' property has not been set. This is required to execute the hashing algorithm.

HashedCredentialsMatcher类中set方法非常规,set方法为:setHashAlgorithmName

为什么这么设置凭证匹配器?

自定义MyRealm extends AuthorizingRealm,实现两个抽象方法

AuthenticationInfo doGetAuthenticationInfo()来自于AuthenticatingRealm类,获取认证数据

AuthorizationInfo doGetAuthorizationInfo()来自于AuthorizingRealm类,获取授权数据

public class MyRealm extends AuthorizingRealm {

    @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
String principal =(String) authenticationToken.getPrincipal();
//userDao.queryUserByUserName
SqlSession sqlSession = null;
try {
sqlSession = MySqlSession.getSqlSession();
} catch (IOException e) {
e.printStackTrace();
}
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserByUserName(principal); /*
* ByteSource.Util.bytes("salt") 盐字段来自数据库,凭证匹配器不能写死盐值
* 安全管理器可以获取到AuthenticationInfo中的盐值 对用户界面的凭证加密
* */
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal,user.getPassword(),ByteSource.Util.bytes("salt"),this.getName());
return authenticationInfo;
} @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取身份信息 Principal用户名、手机号、邮箱地址等 一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
/*
* 用户----角色----权限
* 中间表 中间表
* */
//由primaryPrincipal查库--->获得角色info ---->获取权限info
SqlSession sqlSession = null;
try {
sqlSession = MySqlSession.getSqlSession();
} catch (IOException e) {
e.printStackTrace();
}
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserByUserName(primaryPrincipal);
//测试基于角色的授权
/*if (primaryPrincipal.equals(user.getUsername())){
// class SimpleAuthorizationInfo implements AuthorizationInfo
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addRole("super");
return authorizationInfo;
}*/
//测试基于资源的授权
if(primaryPrincipal.equals(user.getUsername())){
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addStringPermission("user:delete");
authorizationInfo.addStringPermissions(Arrays.asList("admin:delete","admin:add"));
return authorizationInfo;
}
return null;
}
}

一张图看懂认证授权关系:

授权的api

  • 基于角色

                //判断当前主体是否包含此角色
    boolean b = subject.hasRole("super");
    List<String> list = Arrays.asList("super", "admin");
    //判断当前主体是否包含某个角色
    boolean[] booleans = subject.hasRoles(list);
    //判断当前主体是否包含全部的角色
    boolean b = subject.hasAllRoles(list);
  • 基于资源

                boolean b = subject.isPermitted("admin:delete");
    String[] strs={"admin:delete", "admin:add"};
    boolean[] permitted = subject.isPermitted(strs);
    boolean permittedAll = subject.isPermittedAll(strs);

资源权限的标识符

权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

例子:

  • 用户创建权限:user:create,或user:create:*
  • 用户修改实例001的权限:user:update:001
  • 用户实例001的所有权限:user:*:001

Java环境下shiro的测试-认证与授权的更多相关文章

  1. NLPIR分词工具的使用(java环境下)

    一.NLPIR是什么? NLPIR(汉语分词系统)由中科大张华平博士团队开发,主要功能包括:中文分词,词性标注,命名实体识别,用户词典功能,详情见官网:http://ictclas.nlpir.org ...

  2. Java 环境下使用 AES 加密的特殊问题处理

    在 Java 环境下使用 AES 加密,在密钥长度和字节填充方面有一些比较特殊的处理. 1. 密钥长度问题 默认 Java 中仅支持 128 位密钥,当使用 256 位密钥的时候,会报告密钥长度错误 ...

  3. 《安卓网络编程》之第一篇 java环境下模拟客户端、服务器端

    1.Socket简介 在网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个 ...

  4. 这是关于FastJson的一个使用Demo,在Java环境下验证的

    public class User { private int id; private String name; public int getId() { return id; } public vo ...

  5. 1、 Shiro框架:认证,授权(验权 2. Shiro框架实现权限控制方式:

    1. Shiro框架:认证,授权(验权) a) 认证逻辑:applicationCode—>通过工具类获取subject对象,调用login方法参数令牌信息->安全管理器------> ...

  6. 用户登录安全框架shiro—用户的认证和授权(一)

     ssm整合shiro框架,对用户的登录操作进行认证和授权,目的很纯粹就是为了增加系统的安全线,至少不要输在门槛上嘛. 这几天在公司独立开发一个供公司内部人员使用的小管理系统,客户不多但是登录一直都是 ...

  7. spring-security-4 (5)spring security Java配置实现自定义表单认证与授权

    前面三篇讲解了spring security的搭建以及简单的表单认证与授权原理.本篇将实现我们自定义的表单登录与认证.  本篇不会再讲项目的搭建过程,因为跟第二节的搭建如出一辙.本篇也不会将项目中所有 ...

  8. 【转载】Selenim入门环境的搭建--Java环境下的Java Maven Project

    一.开发环境 操作系统: xp win7 win8 win10都可以 JDK: 1.6或者1.7 下载地址 JDK1.7下载 Eclipse: 官网下载比较新的版本,建议下载EE的版本  eclips ...

  9. 如何在Java 环境下使用 HTTP 协议收发 MQ 消息

    1. 准备环境在工程 POM 文件添加 HTTP Java 客户端的依赖. <dependency> <groupId>org.eclipse.jetty</groupI ...

随机推荐

  1. Installation Guide of Ubuntu 14.04, 64bit on Dell Server

    Installation Guide of Ubuntu 14.04, 64bit on Dell Server 准备:U盘(已通过ultraiso刻录ISO镜像). 1.插入U盘: 2.启动服务器, ...

  2. HDU 4325 Flowers(树状数组+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...

  3. HDU 4315 Climbing the Hill(阶梯博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:由上至下有多个格子,最顶端的是山顶,有多个球,其中有一个球是king,每次可以将球向上移动任意个格子 ...

  4. CodeChef - FNCS Chef and Churu(分块)

    https://vjudge.net/problem/CodeChef-FNCS 题意: 思路: 用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所 ...

  5. MRO和C3算法

    本节主要内容: 1.python多继承 2.python经典类的MRO 3.python新式类的MRO,C3算法 4.super() 一.python多继承 在python中类与类之间可以有继承关系, ...

  6. NativeWindow_02_DialogBoxParam_VC6

    PS: 代码参考于<<Windows环境下32位汇编语言程序设计.chm>>,第5章,"5.4 对 话 框(2)" . ZC: 与CreateWindow( ...

  7. 总要先爬出坑的JEE架构

    先来看看官网对它的定义. Java平台企业版(Java EE)是社区驱动的企业软件的标准.Java EE是使用Java Community Process开发的,其中包括来自行业专家,商业和开源组织, ...

  8. git的安装以及生成ssh key

    安装git 在ubuntu系统下输入以下命令安装git软件: sudo apt-get install git 输入以下命令查看git是否安装成功: git --version 如下图所示则表示安装成 ...

  9. Altium Designer PCB画板-交互式布局与模块化布局

    交互式布局 (1)为了达到原理图与PCB两两交互,需要在原理图界面和PCB界面都执行菜单命令“Tools-Cross Select Mode”,选择交互按钮

  10. CC2 条理分明-----AACTP教你谈恋爱

      AACTP是一个神奇的地方,这里可以培养你的自信,培养你的沟通表达能力,培养你的领导管理能力:但是你不知道的是AACTP还可以培养你恋爱的本领.想知道是怎么回事吗?听我给你慢慢说来.我把恋爱分为三 ...