Shiro身份认证授权原理
2017-07-29 17:13
591 查看
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.SecurityManagersecurityManager = 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 权限框架认证和授权原理介绍
- 基于AOP实现权限管理:通过shiro认证身份和模拟授权认证
- Shiro ---身份认证、授权
- 通过shiro认证身份和模拟授权认证
- JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法、shiro认证与shiro授权
- 学习shiro很好的文章===加深了对shiro授权的理解 (认证就是登录好理解)
- springmvc+shiro+maven 实现登录认证与权限授权管理
- shiro认证授权流程
- Shiro学习随笔【二】身份认证
- Shiro学习随笔【二】身份认证
- shiro权限框架中的认证和授权过程
- Shiro简单授权原理分析
- OAuth2.0认证和授权原理
- Shiro AuthenticationException 身份认证异常
- SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能
- 【Shiro】Shiro从小白到大神(三)-权限认证(授权)
- 集软件授权、课件保护和身份认证于一身的加密狗
- Spring-shiro源码陶冶-AuthorizingRealm用户认证以及授权
- 初学 shiro —— 登录认证与授权
- 使用Apache Shiro进行身份认证-proxool配置