一、自定义Realm授权

  前提:认证通过,查看Realm接口的继承关系结构图如下,要想通过自定义的Realm实现授权,只需继承AuthorizingRealm并重写方法即可

二、实现过程

1、新建module,添加如下pom依赖

<properties>
<shiro.version>1.4.1</shiro.version>
<loggingg.version>1.2</loggingg.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${loggingg.version}</version>
</dependency>
</dependencies>

2、新建UserRealm类继承AuthorizingRealm,重写方法

public class UserRealm extends AuthorizingRealm {
private UserService userService = new UserServiceImpl();
private RoleService roleService = new RoleServiceImpl();
private PermissionService permissionService = new PermissionServiceImpl(); /**
* 做认证
*
* @param token
* @return
* @throws AuthenticationException
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = token.getPrincipal().toString();
System.out.println("自定义Realm:" + username);
User user = userService.queryUserByUserName(username);
if (user != null) {
List<String> roles = roleService.queryRoleByUserName(username);
List<String> permissions = permissionService.queryPermissionByUserName(username);
ActivityUser activityUser = new ActivityUser(user, roles, permissions);
//参数1:可以传任意对象|参数2:数据库中的用户密码|参数3:当前类名
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(activityUser, user.getPwd(), this.getName());
return info;
} else {
return null;
}
} //授权方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
System.out.println("doGetAuthorizationInfo被回调了");
//
Object primaryPrincipal = principal.getPrimaryPrincipal();
System.out.println(primaryPrincipal); ActivityUser activityUser = (ActivityUser) principal.getPrimaryPrincipal();
List<String> roles = activityUser.getRoles();
if (roles != null && roles.size() > 0) {
info.addRoles(roles);
}
List<String> permissins = activityUser.getPermissins();
if (permissins!=null&&permissins.size()>0)
{
info.addStringPermissions(permissins);
}
//判断如果是超级管理员
//info.addStringPermission("*:*");
return info;
}

3、test类测试方法

public class TestAuthorizationRealm
{
public static void main(String[] args)
{
//1.模拟前台传递的用户名和密码
String username = "zhangsan";
String password = "123456";
//2.创建安全管理器的工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//3.通过安全管理器工厂获取安全管理器
DefaultSecurityManager securityManager = (DefaultSecurityManager)factory.getInstance();
//4.创建自定义的Realm
UserRealm userRealm = new UserRealm();
//5.设置自定义的Realm
securityManager.setRealm(userRealm);
//6.将安全管理器绑定到当前运行环境
SecurityUtils.setSecurityManager(securityManager);
//7.从当前环境中获取Subject主体
Subject subject1 = SecurityUtils.getSubject();
//8.调用主体的登录方法
try
{
subject1.login(new UsernamePasswordToken(username,password));
System.out.println("登录成功~"); // Object principal = subject1.getPrincipal();
// System.out.println(principal); } catch (IncorrectCredentialsException e) {
System.out.println("密码不正确");
}catch (UnknownAccountException e) {
System.out.println("用户名不存在");
} boolean role1 = subject1.hasRole("role1");
boolean role2 = subject1.hasRole("role1");
System.out.println(role1); boolean permitted = subject1.isPermitted("user:add");
System.out.println(permitted);
}
}

三、分析

1、在进行授权的时候,每进行一次授权都会进行一次回调自定义Realm的doGetAuthorizationInfo方法,验证如下:

①在授权方法内部打印日志

②test类做3次授权,查看控制台如下:

2、认证时候进行查库,查角色、权限,并封装对象,避免多次调用授权方法导致频繁查库导致性能下降

四、总结

1、每次进行授权时,就会调用授权方法(通过打印日志可以验证)

2、避免在授权回调方法中查库而导致性能下降

3、授权方法参数可以获取到认证方法中放入的第一个任意参数(图中有说明,当然也可以通过subject.getPrincipal()方法获取该参数),所以我采用封装的方式,实现多次调用授权方法时也是同一个对象,避免频繁查库

Shiro入门学习之自定义Realm实现授权(五)的更多相关文章

  1. Shiro入门学习之自定义Realm实现认证(四)

    一.概述 Shirom默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,而大部分情况下需要从系统数据库中读取用户信息,所以需要实现自定义Realm,Realm接口如下: ...

  2. Shiro入门学习---使用自定义Realm完成认证|练气中期

    写在前面 在上一篇文章<shiro认证流程源码分析--练气初期>当中,我们简单分析了一下shiro的认证流程.不难发现,如果我们需要使用其他数据源的信息完成认证操作,我们需要自定义Real ...

  3. Shiro入门学习之shi.ini实现授权(三)

    一.Shiro授权 前提:需要认证通过才会有授权一说 1.授权过程 2.相关方法说明 ①subject.hasRole("role1"):判断是否有该角色 ②subject.has ...

  4. shiro入门学习--使用MD5和salt进行加密|练气后期

    写在前面 在上一篇文章<Shiro入门学习---使用自定义Realm完成认证|练气中期>当中,我们学会了使用自定义Realm实现shiro数据源的切换,我们可以切换成从关系数据库如MySQ ...

  5. Shiro入门学习与实战(一)

    一.概述 1.Shiro是什么? Apache Shiro是java 的一个安全框架,主要提供:认证.授权.加密.会话管理.与Web集成.缓存等功能,其不依赖于Spring即可使用: Spring S ...

  6. shiro学习笔记_0600_自定义realm实现授权

    博客shiro学习笔记_0400_自定义Realm实现身份认证 介绍了认证,这里介绍授权. 1,仅仅通过配置文件来指定权限不够灵活且不方便.在实际的应用中大多数情况下都是将用户信息,角色信息,权限信息 ...

  7. shiro入门学习--授权(Authorization)|筑基初期

    写在前面 经过前面的学习,我们了解了shiro中的认证流程,并且学会了如何通过自定义Realm实现应用程序的用户认证.在这篇文章当中,我们将学习shiro中的授权流程. 授权概述 这里的授权指的是授予 ...

  8. Shiro入门学习之散列算法与凭证配置(六)

    一.散列算法概述 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5.SHA等,一般进行散列时最好提供一个salt(“盐”),什么意思?举个栗子 ...

  9. shiro框架学习-5-自定义Realm

    1. 自定义Realm基础 步骤: 创建一个类 ,继承AuthorizingRealm->AuthenticatingRealm->CachingRealm->Realm 重写授权方 ...

随机推荐

  1. How to Create an OCM Response file to Apply a Patch in Silent Mode - opatch silent

    Windows Server 2019 打补丁时缺少Oracle Configuration Manager(OCM) 响应文件处理方式. 适用: Oracle Universal Installer ...

  2. C++ windows线程操作(转)

    参考 1._beginthreadex创建线程 DWORD m_dwMSGTID; // 线程ID HANDLE m_hMSG; // 线程句柄 m_hMSG = (HANDLE)_beginthre ...

  3. axios中then不用第二个参数,最好用catch

    一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法. // bad promise .then(function(data) { // ...

  4. Python(三):环境及其配置

    一,PYTHONPATH 默认的Python模块搜索路径,可以将路径指向anaconda3,需要开发者自己设置 二,PYTHONHASHSEED 如果该环境变量被设定为 random ,相当于 -R ...

  5. 常见css属性

    div {            width: 100px;            height: 100px;            /* 表示行高 */            line-heigh ...

  6. setInterval 和 setTimeout 定时器

    前端定时器 setInterval 和 setTimeout setInterval 循环执行 循环执行就是设置一个时间间隔,每过一段时间都会执行一次这个方法,直到这个定时器被销毁掉. 用法是setI ...

  7. C语言是菜鸟和大神的分水岭

    作为一门古老的编程语言,C语言已经坚挺了好几十年了,初学者从C语言入门,大学将C语言视为基础课程.不管别人如何抨击,如何唱衰,C语言就是屹立不倒:Java.C#.Python.PHP.Perl 等都有 ...

  8. springmvc、 springboot 项目全局异常处理

    异常在项目中那是不可避免的,通常情况下,我们需要对全局异常进行处理,下面介绍两种比较常用的情况. 准备工作: 在捕获到异常的时候,我们通常需要返回给前端错误码,错误信息等,所以我们需要手动封装一个js ...

  9. curl模板----php发送post,get请求

    function _grab($curl,$ip='',$referer='',$postInfo='',$cookie=''){ $ch = curl_init(); curl_setopt($ch ...

  10. kuangbin专题 专题九 连通图 POJ 1236 Network of Schools

    题目链接:https://vjudge.net/problem/POJ-1236 题目:有向图,有若干个连通图,点之间有单向边边就可以单向传递信息,问: (1)至少需要发送几份信息才能使得每个点都传递 ...