Shiro认证、授权案例讲解

一、认证

 1、 认证流程

   

2、用户密码已经加密、加盐的用户认证

(1)测试类

  // 用户登陆和退出,这里我自定了一个realm(开发肯定需要自定义realm获取数据库密码和权限)
@Test
public void testCustomRealmMd5() { // 创建securityManager工厂,通过ini配置文件创建securityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-realm-md5.ini"); // 创建SecurityManager
SecurityManager securityManager = factory.getInstance(); // 将securityManager设置当前的运行环境中
SecurityUtils.setSecurityManager(securityManager); // 从SecurityUtils里边创建一个subject
Subject subject = SecurityUtils.getSubject(); // 在认证提交前准备token(令牌)
// 这里的账号和密码 将来是由用户输入进去
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "111111"); try {
// 执行认证提交
subject.login(token);
} catch (AuthenticationException e) {
e.printStackTrace();
} // 是否认证通过
boolean isAuthenticated = subject.isAuthenticated(); System.out.println("加密后是否认证通过:" + isAuthenticated);
// 退出操作
subject.logout();
// 是否认证通过
isAuthenticated = subject.isAuthenticated();
System.out.println("退出后是否认证通过:" + isAuthenticated);
}

(2)shiro-realm-md5.ini (有关散列加密下面会举例子)

我在ini配置了加密的规则,这个规则要和用户注册保存的密码加密规则一致。

[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1 #将凭证匹配器设置到realm
customRealm=com.jincou.shiro.realm.CustomRealmMd5
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm

(3)自定义CustomRealmMd5类

/**
*自定义Realm特点
*(1)继承AuthorizingRealm类
*(2)重写AuthenticationInfo(认证)
* doGetAuthorizationInfo(授权)两个方法
* 注意:
* 1:这里password = "f3694f162729b7d0254c6e40260bf15c"肯定也是通过明文(这里指zhangsan)+盐(这里是qwerty)进行加密后的字符串
* 2:实际应用是将盐和散列后的值存在数据库中,自动realm从数据库取出盐和加密后的值由shiro完成密码校验。
* 3:这里要注意它们两的加密规则一定要一致,否则无法比较。
*/
public class CustomRealmMd5 extends AuthorizingRealm { // 设置realm的名称(任意和其它也无关联)
@Override
public void setName(String name) {
super.setName("customRealmMd5");
} // 用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException { System.out.println("测试..自定义CustomRealmMd5方法里面......"); // token是用户输入的
// 第一步从token中取出身份信息
String userCode = (String) token.getPrincipal(); // 第二步:根据用户输入的userCode从数据库查询
// .... //如果数据库查询不到zhangsan用户信息,则返回null
/*if(user==null){
return null;
}*/ // 模拟从数据库查询到密码,散列值
String password = "f3694f162729b7d0254c6e40260bf15c";
// 从数据库获取salt
String salt = "qwerty";
//上边散列值和盐对应的明文:111111 // 如果查询到返回认证信息AuthenticationInfo,这里的密码加密判断交给底层处理
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
userCode, password, ByteSource.Util.bytes(salt), this.getName()); return simpleAuthenticationInfo;
} // 用于授权(后面写)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
return null;
}
}

运行效果

结论:subject.login(token)我在提交认证,它就会去调用我自定义的CustomRealm,因为我在ini进行配置自定义CustomRealm

 3、加密算法

因为在ini里面配置的加密规则,那我第一次用户注册的时候,肯定也需要按它的规则进行加密后,把密码保存到数据库

  /**
* 加密算法
*/
public class MD5Test {
public static void main(String[] args) {
//原始 密码
String source = "111111";
//盐
String salt = "qwerty"; //散列次数(和ini中credentialsMatcher.hashIterations=1一致)
int hashIterations = 1;
//上边散列1次:f3694f162729b7d0254c6e40260bf15c
//上边散列2次:36f2dfa24d0a9fa97276abbe13e596fc //第一个参数:散列算法
//这里的散列算法是md5要和ini中credentialsMatcher.hashAlgorithmName=md5一致)
//第二个参数:明文,原始密码
//第三个参数:盐,通过使用随机数
//第四个参数:散列的次数,比如散列两次,相当 于md5(md5(''))
SimpleHash simpleHash = new SimpleHash("md5", source, salt, hashIterations);
System.out.println(simpleHash.toString());
}
}
//这个结果:f3694f162729b7d0254c6e40260bf15c就是在自定义realm中的密文也就是该用户保存到数据库中的密文。

二、授权(基于资源的授权)

 1、授权流程

2、授权方式

Shiro 支持三种方式的授权:
(1)编程式:通过写if/else 授权代码块完成:

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}

(2)注解式:通过在执行的Java方法上放置相应的注解完成

@RequiresRoles("admin")
public void hello() {
//有权限
}

3)JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成

<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>

这里授权测试使用第一种编程方式,实际与web系统集成使用后两种方式。

 3、授权测试

(1)测试类

// 自定义realm进行资源授权测试
@Test
public void testAuthorizationCustomRealm() { // 创建SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-realm.ini"); // 创建SecurityManager
SecurityManager securityManager = factory.getInstance(); // 将SecurityManager设置到系统运行环境,和spring后将SecurityManager配置spring容器中,一般单例管理
SecurityUtils.setSecurityManager(securityManager); // 创建subject
Subject subject = SecurityUtils.getSubject(); // 创建token令牌
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
"111111"); // 执行认证
try {
subject.login(token);
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} System.out.println("认证状态:" + subject.isAuthenticated());
// 认证通过后执行授权 // 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据
// isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内
boolean isPermitted = subject.isPermitted("user:create:1");
System.out.println("单个权限判断" + isPermitted); boolean isPermittedAll = subject.isPermittedAll("user:create:1",
"user:create");
System.out.println("多个权限判断" + isPermittedAll); // 使用check方法进行授权,如果授权不通过会抛出异常
subject.checkPermission("items:add:1"); }

(2)shiro-realm.ini

[main]
#自定义 realm
customRealm=com.jincou.shiro.realm.CustomRealm
#将realm设置到securityManager
securityManager.realms=$customRealm

(3)自定义CustomRealm类

public class CustomRealm extends AuthorizingRealm {

    // 用于认证(上面写过)
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
return null;
} // 用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) { //从 principals获取主身份信息
//将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
String userCode = (String) principals.getPrimaryPrincipal(); //根据身份信息获取权限信息
//连接数据库...
//模拟从数据库获取到数据
List<String> permissions = new ArrayList<String>();
permissions.add("user:create");//用户的创建
permissions.add("items:add");//商品添加权限
//.... //查到权限数据,返回授权信息(要包括 上边的permissions)
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//将上边查询到授权信息填充到simpleAuthorizationInfo对象中
simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo;
}
}

运行结果:

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。少校【5】

【shiro】(4)---Shiro认证、授权案例讲解的更多相关文章

  1. SpringBoot整合Shiro 四:认证+授权

    搭建环境见: SpringBoot整合Shiro 一:搭建环境 shiro配置类见: SpringBoot整合Shiro 二:Shiro配置类 shiro整合Mybatis见:SpringBoot整合 ...

  2. 5、Shiro之jdbcRealm认证授权

    登录认证: 注意,下面我是以连接orcal数据库为例的依赖,如果各位同仁使用的是骑她数据库,可以换成对应数据库的依赖(数据源不用换) Pom.xml增加依赖: <!--引入连接orcal的jar ...

  3. springboot系列(十)springboot整合shiro实现登录认证

    关于shiro的概念和知识本篇不做详细介绍,但是shiro的概念还是需要做做功课的要不无法理解它的运作原理就无法理解使用shiro: 本篇主要讲解如何使用shiro实现登录认证,下篇讲解使用shiro ...

  4. Shiro 核心功能案例讲解 基于SpringBoot 有源码

    Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...

  5. SpringBoot整合shiro实现用户的认证授权

    * 项目环境搭建 * 配置ShiroConfig,用于shiro的基本配置和注入自定义规则 * 实现自定义的realm,继承AuthorizingRealm * 编写测试controller和页面 基 ...

  6. Java环境下shiro的测试-认证与授权

    Java环境下shiro的测试 1.导入依赖的核心jar包 <dependency> <groupId>org.apache.shiro</groupId> < ...

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

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

  8. Shiro身份认证授权原理

    shiro在应用程序中的使用是用Subject为入口的, 最终subject委托给真正的管理者ShiroSecurityMannager Realm是Shiro获得身份认证信息和来源信息的地方(所以这 ...

  9. SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能

    SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能. 第一步:配置web.xml <!-- 配置Shiro过滤器,先让Shiro ...

随机推荐

  1. 文件操作命令(replace)

    Replace 命令: // 描述: 替换文件. // 语法: REPLACE [drive1:][path1]filename [drive2:][path2] [/A] [/P] [/R] [/W ...

  2. mysql从的配置文件

    mysql 从的配置文件 [client]port = 3306socket = /data/mysql/data/mysql.sock#default-character-set=utf8[mysq ...

  3. easy-ui treegrid 实现分页 并且添加自定义checkbox

    首先第一点easy-ui  treegrid 对分页没有好的实现, 因为在分页的过程中是按照 根节点来分页的  后台只能先按照 根节点做分页查询  再将子节点关联进去, 这样才能将treegrid 按 ...

  4. Java实现AES加密,异常java.security.InvalidKeyException: Illegal key size 的解决

    Java实现AES加密,抛出异常如下:java.security.InvalidKeyException: Illegal key size 代码参考 http://my.oschina.net/Ja ...

  5. CentOS下安装Git

    在终端输入命令:yum install git,此时会进行提示安装,输入y, 在这种安装方式下,速度很快(windows系统下下载客户端速度超慢),当出现安装完毕时,就可以了. 安装完毕后输入git ...

  6. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  7. springcloud+zuul+swagger 分布式接口文档

    https://gitee.com/didispace/swagger-butler 1.引用上面项目中的swagger 工具包 2.zuul 网关配置 zuul.routes.api-apiserv ...

  8. vuex创建store并用computed获取数据

    vuex中的store是一个状态管理器,用于分发数据.相当于父组件数据传递给子组件. 1.安装vuex npm i vuex --save 2.在src目录中创建store文件夹,里面创建store. ...

  9. linux 解压 压缩 常见命令

    压缩命令: .tar tar -cvf 文件名称.tar 文件或者文件夹 .tar.gz tar -zcvf 文件名称.tar.gz 文件或者文件夹 .tar.xz tar -Jcf 文件名称.tar ...

  10. java注解的实质,何为注解

    注解就是贴标签 (1)注解的作用 1,生成文档.如常用的@param 2,跟踪代码依赖性,实现替代文件的功能.在spring中,主要是减少配置. 3,编译时进行格式检查.如常用的@override ( ...