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

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

身份认证过程

自定义realm代码

public class myRealm  extends AuthorizingRealm  {
        //realm的名称
	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "myRealm";
	}
        //验证token是否是有效的token
	@Override
	public boolean supports(AuthenticationToken arg0) {
		// TODO Auto-generated method stub
		return arg0 instanceof UsernamePasswordToken;
	}
        //授权获得用户权限信息的方法
	@Override
	protected 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 stub
		return info;
	}
         //认证获取用户身份信息的方法
	@Override
	protected 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 stub
			SimpleAuthenticationInfo 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 返回回去


   //授权获得用户权限信息的方法
    @Override
    protected 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 stub
        return info;
    }

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

WildcardPermission 这个又是什么意思呢。。通过addStringPermission  默认是用Permission的实现类封装的 如果我们又定义就用我们的封装 没有定义就用默认的WildcardPermission最终将他们保存到一个集合里面如:
public class MyPermission implements Permission {

    String permissionCode;
    public MyPermission(String name) {
        permissionCode=name;
    }

    @Override
    public boolean implies(Permission permission) {
        //自定义比较
        // TODO Auto-generated method stub
        return false;
    }

}

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

SecurityManager 
SecurityManager 再将指令传达给授权管理类Authorizer
Authorizer会通过reaml获得授权信息SimpleAuthorizationInfo如果我们返回的授权信息拥有角色 会调用RolePermissionResolver实现类的方法 将角色的权限追加到SimpleAuthorizationInfo(默认是没有实现的)如:
public class MyRolePermissionResolver  implements RolePermissionResolver{

    @Override
    public Collection<Permission> resolvePermissionsInRole(String roleString) {
        // TODO Auto-generated method stub
         return 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

Shiro身份认证授权原理的更多相关文章

  1. Apache shiro集群实现 (三)shiro身份认证(Shiro Authentication)

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  2. Shiro身份认证---转

    目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...

  3. [认证授权] 5.OIDC(OpenId Connect)身份认证授权(扩展部分)

    在上一篇[认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)中解释了OIDC的核心部分的功能,即OIDC如何提供id token来用于认证.由于OIDC是一个协议族,如果 ...

  4. asp.net core 使用identityServer4的密码模式来进行身份认证(2) 认证授权原理

    前言:本文将会结合asp.net core 认证源码来分析起认证的原理与流程.asp.net core版本2.2 对于大部分使用asp.net core开发的人来说. 下面这几行代码应该很熟悉了. s ...

  5. Shiro学习总结(3)——Apache Shiro身份认证

    身份验证,即在应用中谁能证明他就是他本人.一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明. 在shiro中,用户需要提供principals (身份)和cre ...

  6. Shiro身份认证、盐加密

    目的: Shiro认证 盐加密工具类 Shiro认证 1.导入pom依赖 <dependency> <groupId>org.apache.shiro</groupId& ...

  7. CVE-2020-17523:Apache Shiro身份认证绕过漏洞分析

    0x01 Apache Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 0x02 漏洞简介 2021年2月1日,Apache Shiro官 ...

  8. [认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)

    0 目录 认证授权系列:http://www.cnblogs.com/linianhui/category/929878.html 1 什么是OIDC? 看一下官方的介绍(http://openid. ...

  9. Shiro身份认证-JdbcRealm

    Subject 认证主体 Subject认证主体包含两个信息 Principals : 身份,可以是用户名.邮箱.手机号等,用来标识一个登录主体身份. Credentials : 凭证,常见有密码,数 ...

随机推荐

  1. SQL Server数据库 bcp导出备份文件应用

    /**  * 授权  */ EXEC sp_configure 'show advanced options',1; go reconfigure; go exec sp_configure 'xp_ ...

  2. luogu2437 蜜蜂路线

    题目大意 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房M开始爬到蜂房N,M<N,有多少种爬行路线?M,N<=1000 题解 看到M ...

  3. css3 animate基本属性

    Css3animate属性 属性 描述 Css Animation 所有动画属性的简写属性,除了animation-play-state属性 Animation:name duration timin ...

  4. docker(部署常见应用):docker部署mysql

    上节回顾:docker(部署常见应用):docker部署nginx docker部署mysql:5.7.26 # 下载镜像 docker pull mysql: # 查看镜像 docker image ...

  5. GStreamer基础教程01 - Hello World

    摘要 在面对一个新的软件库时,第一步通常实现一个“hello world”程序,来了解库的用法.对于GStreamer,我们可以实现一个极简的播放器,来了解GStreamer的使用. 环境配置 为了快 ...

  6. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  7. oracle11g安装与拆卸

    Oracle 11g安装 1.解压下载的包,然后进入包内,点击setup.exe开始安装 . 2.出现如下:一般把那个小对勾取消,点击下一步进行, 弹出下图这个后点'是' 3.下图后,选择创建和配置数 ...

  8. Linux学习笔记(Redhat)

    一.开始 linux平台上的开发 vi.gcc.gdb.make.jdk.tomcat.mysql. linux基本操作 c语言功底<c专家编程>和java语言 学习unix高级编程 &l ...

  9. Caffe: Caffe的Python接口

    官方参考:http://caffe.berkeleyvision.org/installation.html 官方介绍是这样的: Python The main requirements are nu ...

  10. Juery实现选项卡

    选项卡是一种很常用的组件.比如3个选项的选项卡,比较笨的一种办法是,把3个状态写成3个独立页面,互相链接.这样做的问题也显而易见,切换的时候url会变.如果是手机端网页,加载慢一点,给人的感觉是不断的 ...