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. UFT(QTP)中的Object Repository

    Object Repository 是对象的仓库,UFT所用到的所有界面对象元素都存储在这里,并且也存储了该对象的属性,如对象名称title,对象的位置,对象的属性(button,list....) ...

  2. ROS探索总结(十九)——怎样配置机器人的导航功能

    1.概述 ROS的二维导航功能包.简单来说.就是依据输入的里程计等传感器的信息流和机器人的全局位置,通过导航算法,计算得出安全可靠的机器人速度控制指令. 可是,怎样在特定的机器人上实现导航功能包的功能 ...

  3. 好吧,我承认我喜欢这种多个 StoryBoard 组织的方式,学习了!

    下面转载内容非常不错.兴许补充从官方文档疏理出来的脉络,确实非常好的使用方法. tid-270505.html"> tid-270505.html">Storyboar ...

  4. UVa 11722(几何概率)

    题意:你和你的朋友要乘坐火车,并且都会在A城市相遇,你会在(t1,t2)中的任意时刻以相同的概率密度到达, 你朋友会在(s1,s2)中的任意时刻以相同的概率密度到达,你们的火车在A城市都会停留w分钟, ...

  5. [POJ 3345] Bribing FIPA

    [题目链接] http://poj.org/problem?id=3345 [算法] 树形背包 [代码] #include <algorithm> #include <bitset& ...

  6. SQL server存储过程学习

    由于之前使用 Linq to Sql来操作数据库,对于数据库的存储过程.函数等比较薄弱.乘着自己闲着的时候,就百度自学了一点存储过程,以防以后要用. 基础通俗易懂的存储过程通过 存储过程学习 ,然后自 ...

  7. Android View事件分发与传递

    在Android中,人们主要通过手指与系统交互.Android把所有的touch事件都被封装成MotionEvent来进行处理,其中包括了手指点击的位置,时间等信息.其事件类型主要包括:ACTION_ ...

  8. CSS3实现简单的幻灯片

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 使用Micrisoft.net设计方案 前言

    前言 主要阐述23种设计模式在Microsoft.Net中的使用,以及使用设计模式创建后的对象如何使用.同是向我们传达3个理念,分别是: 1.  使用设计模式可以让程序更加灵活 2.  结构越复杂,意 ...

  10. JavaScript数组和json的区别

    <html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...