Shiro身份认证授权原理

shiro在应用程序中的使用是用Subject为入口的, 最终subject委托给真正的管理者ShiroSecurityMannager

Realm是Shiro获得身份认证信息和来源信息的地方(所以这里是我们实现的)我们只要继承他的实现类重写方法就好了,AuthorizingRealm 

身份认证过程

自定义realm代码

public class myRealm  extends AuthorizingRealm  {//realm的名称@Overridepublic String getName() {// TODO Auto-generated method stubreturn "myRealm";}//验证token是否是有效的token@Overridepublic boolean supports(AuthenticationToken arg0) {// TODO Auto-generated method stubreturn arg0 instanceof UsernamePasswordToken;}//授权获得用户权限信息的方法@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();info.addRole("321");info.addRole("3332");info.addStringPermission("333");info.addStringPermission("555");info.addObjectPermission(new WildcardPermission("44"));// TODO Auto-generated method stubreturn info;}//认证获取用户身份信息的方法@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken loginToken=(UsernamePasswordToken)token;String password=new String(loginToken.getPassword());System.out.println(password);System.out.println(loginToken.getUsername());if(loginToken.getUsername()=="zhang"&&password.equals("123")){}else{throw new IncorrectCredentialsException();}// TODO Auto-generated method stubSimpleAuthenticationInfo info= new SimpleAuthenticationInfo(loginToken.getUsername(),password,getName());return info;}}

  

doGetAuthorizationInfo方法是进行用户授权的时候调用的方法 用户获得当前用户的授权信息 先不管他
doGetAuthenticationInfo是当我们调用subject.login进行认证的方法 这个方法的参数token就是我们subject.login调用的
这里面我们就可以查询数据库对用户名和密码进行认证
如果认证成功将用户信息封装成SimpleAuthenticationInfo
认证失败根据几种情况抛出异常,常见的如:
DisabledAccountException(禁用的帐号)、LockedAccountException(锁定的帐号)
UnknownAccountException(错误的帐号)
ExcessiveAttemptsException(登录失败次数过多)、IncorrectCredentialsException (错误的凭证)
ExpiredCredentialsException(过期的凭证)等

shiro.ini配置

#声明一个realm  
myRealm1=com.liqiang.realm.myRealm
#这里就是我们注入realm的地方 
securityManager.realms=$myRealm1

 

实现身份认证的代码

	@Test  public void testHelloworld() {  //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager  Factory<org.apache.shiro.mgt.SecurityManager> factory =  new IniSecurityManagerFactory("classpath:shiro.ini");  //2、得到SecurityManager实例 并绑定给SecurityUtils  org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();  SecurityUtils.setSecurityManager(securityManager);  //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)  Subject subject = SecurityUtils.getSubject();  UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");  try {  //4、登录,即身份验证  subject.login(token);  } catch (AuthenticationException e) {  //5、身份验证失败  }  subject.logout();  }  

上面我们调用sbuject.login(token) 这个token封装了前端用户输入的用户名和密码

 

授权验证

 当我们通过subject.isPermitted("user:update") 当我们判断当前用户是否拥有user:update这个权限代码的时候

会调用我们ream的 doGetAuthorizationInfo 方法获得授权信息。我们在这里面就是根据用户信息查询数据将认证信息封装

SimpleAuthorizationInfo 返回回去

   //授权获得用户权限信息的方法
    @Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();info.addRole("321");info.addRole("3332");info.addStringPermission("333");info.addStringPermission("555");info.addObjectPermission(new WildcardPermission("44"));// TODO Auto-generated method stubreturn info;}

这里通过查询数据库知道用户有321  332  这2个角色 和 333   555   44  这几个权限

WildcardPermission 这个又是什么意思呢。。通过addStringPermission  默认是用Permission的实现类封装的 如果我们又定义就用我们的封装 没有定义就用默认的WildcardPermission
最终将他们保存到一个集合里面
如:
public class MyPermission implements Permission {String permissionCode;public MyPermission(String name) {permissionCode=name;}@Overridepublic boolean implies(Permission permission) {//自定义比较// TODO Auto-generated method stubreturn false;}}

当我们调用subject.isPermitted("user:update")会调用将指令传达给

SecurityManager 
SecurityManager 再将指令传达给授权管理类Authorizer
Authorizer会通过reaml获得授权信息SimpleAuthorizationInfo
如果我们返回的授权信息拥有角色 会调用RolePermissionResolver实现类的方法 将角色的权限追加到SimpleAuthorizationInfo(默认是没有实现的)
如:
public class MyRolePermissionResolver  implements RolePermissionResolver{@Overridepublic Collection<Permission> resolvePermissionsInRole(String roleString) {// TODO Auto-generated method stubreturn Arrays.asList((Permission)new MyPermission("menu:*")); }

这里面应该是根据角色查询权限 

最终 遍历SimpleAuthorizationInfo的权限信息 (我们的权限信息都封装Permission接口实现类 调用implies方法进行比较 如果比较成功返回true 表示授权通过)自定义Permission的好处就是我们可以自定义匹配规则

注入自定义Permission和RolePerminssion的配置

[main]
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer  
securityManager.authorizer=$authorizer   
#自定义rolePermissionResolver  
rolePermissionResolver=com.liqiang.permissionResolver.MyRolePermissionResolver 
authorizer.rolePermissionResolver=$rolePermissionResolver  
securityManager.authorizer=$authorizer
permissionResolver=com.liqiang.permissionResolver.MyPermissionResolver
authorizer.permissionResolver=$permissionResolver  
#声明一个realm  
myRealm1=com.liqiang.realm.myRealm
#指定securityManager的realms实现  
securityManager.realms=$myRealm1

 PS:好记性不如烂笔头  希望自己回头来看一下就能回忆起来

        学习文章:http://jinnianshilongnian.iteye.com/blog/2018398

转载于:https://www.cnblogs.com/LQBlog/p/7256777.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/416286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux进程路由策略,linux路由表,策略路由,路由查找

路由表内核中路由表有2种&#xff1a;l 一个是缓存路由(fib)&#xff0c;是自动学习生成自动管理的&#xff0c;用户没必要去干预&#xff0c;但是内核还是提供了方法让用户可以去清空它。但是用户不能设置它的项&#xff0c;但是可以根据这个缓存更新的原理从外部影响他。l 路…

图形桌面linux触摸,新手看招:用图形桌面访问Linux操作系统

创建用户帐户&#xff1a;adduser login-name (OS:Red Hat)useradd login-name (OS:SuSe)为帐户添加密码&#xff1a;passwd login-name (密码应该包括一个数字&#xff0c;且不能为英文单词)结束登录程序&#xff0c;启动另一登录实例&#xff1a;CtrlD从终端启动图形窗口环境…

Python namedtuple(命名元组)使用实例

Python namedtuple(命名元组)使用实例 #!/usr/bin/python3import collectionsMyTupleClass collections.namedtuple(MyTupleClass,[name, age, job]) obj MyTupleClass("Tomsom",12,Cooker) print(obj.name) print(obj.age) print(obj.job)执行结果&#xff1a; To…

pd怎么卸载linux系统,parallels desktop11怎么卸载?parallels desktop11卸载方法

parallels desktop11是一款功能强大的MAC虚拟机软件&#xff0c;用户通过该软件可在mac系统下运行安装windows或Linux操作系统&#xff0c;不过很多时候用户在安装后&#xff0c;由于后期没有使用虚拟机的需求&#xff0c;故此想要将其删除&#xff0c;但是又不知道如何操作&am…

html5中使页面中元素居中

在div中加入 style"text-align: center;

linux下jdk源码安装,Linux JDK 源码安装

一 环境1.1 操作系统[roothost-xxxsoft]# lsb_release -aLSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarchDistributor ID: CentOSDescription: CentOS re…

Python map/reduce

2017-07-31 18:20:59 一、map函数 map()&#xff1a;会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数&#xff0c;返回包含每次 function 函数返回值的iterator,即迭代器&#xff0c;使用list函数可以将之转成列表。 map(f…

linux裸机安装nginx,linux环境下安装nginx步骤 - 进击的乌龟 - 博客园

开始前&#xff0c;请确认gcc g开发类库是否装好&#xff0c;默认已经安装。ububtu平台编译环境可以使用以下指令apt- get install build- essentialapt - get install libtoolcentos平台编译环境使用如下指令安装make&#xff1a;yum -y install gcc automake autoconf libtoo…

Effective C++ 条款21

必须返回对象时。别妄想返回其reference 我们上节分析了对象引用传递的优点&#xff0c;如今说明函数返回引用对象带来的种种坏处。 先来一段代码&#xff1a; class Rational{ public:Rational(int numerator0, int denominator1);…… private:int n, d;friendconst Rationa…

html 中 em

◆px像素&#xff08;Pixel&#xff09;&#xff0c;相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 ◆em是相对长度单位&#xff0c;相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置&#xff0c;则相对于浏览器的默认字体尺寸。 因此用px来定…

c语言命名参数,按照C语言的规定,实参和形参的命名不得重复。

按照羊脂玉具有( )光泽。衡量睡眠质量好坏包括入睡快慢,睡眠深浅,睡后能否解乏(精神情况、规定是否影响日常的工作和生活)三个方面。参和“有药吃而无伙食命亦难保”提示健康普及必须遵循的经济性原则。形参治病与调补都需要辩证,其中区别在于用药与药量的不同。命得重咳嗽除了…

雇佣兵

题目链接&#xff1a;http://noi.openjudge.cn/ch0105/37/ 总时间限制: 1000ms内存限制: 65536kB描述雇佣兵的体力最大值为M&#xff0c;初始体力值为0、战斗力为N、拥有X个能量元素。 当雇佣兵的体力值恰好为M时&#xff0c;才可以参加一个为期M天的战斗期&#xff0c;战斗期结…

织梦的if(!defined('DEDEINC')) exit("Request Error!");解析

1if(!defined(DEDEINC)) exit("Request Error!");细细看看你就会发现,这句代码一般都是在 /include 路径下的php文件里边,为什么 dede 路径下的php文件没有呢&#xff1f;因为 include 路径下的文件是 类文件,也就是 方法文件 ,是以后要被 require_once 引入的文件,M…

阿诺德图像加密c语言,基于Arnold置乱的数字图像加密算法(二)

前文我们介绍了基于Arnold置乱的数字图像加密算法的两种图像置乱变换&#xff0c;今天我们介绍的是另外三种图像置乱变换&#xff1a;基于骑士巡游的图像置乱变换、基于Arnold变换的数字图像置乱和基于仿射变换的置乱变换。一、基于骑士巡游的图像置乱变换所谓骑士巡游&#xf…

python学习(十七) 扩展python

c, c, java比python快几个数量级。 17.1 考虑哪个更重要 开发速度还是运行速度更重要。 17.2 非常简单的途径&#xff1a;Jython和IronPython Jython可以直接访问JAVA标准库。 IronPython中可以直接访问C#标准库。 17.3 编写C语言扩展 扩展Python通常就是扩展CPython&#xff0…

织梦DEDECMS网站留言板提交时验证码错误返回空白页的解决办法

织梦DEDECMS模板网站留言板提交时验证码错误返回空白页的解决办法&#xff1a; 默认情况下&#xff0c;如果我们使用DEDE模板中的默认留言板时&#xff0c;如果留言信息不正确或者输入内容为空时&#xff0c;dedecms系统就会返回一个空白页。 这样的方式很不利于用户体验&#…

android 车辆轨迹,Android自定义view实现车载可调整轨迹线

本文实例为大家分享了Android自定义view完成车载可调整轨迹线的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下同事做的view&#xff0c;拿过来做个记录。/****/package com.text.myviewdemo.view;import org.apache.http.conn.routing.RouteInfo.LayerType;import a…