Authentication概述

概述

Authentication 是指身份验证的过程——即证明一个用户实际上是不是他们所说的他们是谁。也就是说通过提交用户的身份和凭证给Shiro,以判断它们是否和应用程序预期的相匹配。

基本概念

1:Principals(身份):是Subject 的‘identifying attributes(标识属性)’。比如我们登录提交的用户名。

2:Credentials(凭证):通常是只被Subject 知道的秘密值,它用来作为一种起支持作用的证据,此证据事实上包含着所谓的身份证明。比如我们登录提供的密码

认证的基本步骤

1. 收集Subjects 提交的Principals(身份)和Credentials(凭证);

2. 提交Principals(身份)和Credentials(凭证)进行身份验证;

3. 如果提交成功,则允许访问,否则重新进行身份验证或者阻止访问。

认证样例

使用用户名/密码的样例

UsernamePasswordToken token = new UsernamePasswordToken(username, password);

token.setRememberMe(true);

样例使用UsernamePasswordToken 来支持最常见的用户名/密码的身份验证方法。这是Shiro的org.apache.shiro.authc.AuthenticationToken 的接口,是Shiro 代表提交的Principals(身份)和Credentials(凭证)的身份验证系统所使用的基本接口的一个实现。

提交用户名/密码进行认证

Subject currentUser = SecurityUtils.getSubject();

currentUser.login(token);

处理认证成功和失败

如果认证成功,会没有返回,也没有例外,通过。

如果认证失败,会拋出例外,你可以在程序中捕获并处理,如下示例:

try {

currentUser.login(token);

} catch ( UnknownAccountException uae ) { …

} catch ( IncorrectCredentialsException ice ) { …

} catch (LockedAccountException lae ) { …

} catch (ExcessiveAttemptsException eae ) { …

} … catch your own …

nlogout(注销)

currentUser.logout();

当你调用logout,任何现有的Session 都将会失效,而且任何身份都将会失去关联(例如,在Web 应用程序中,RememberMe cookie 也将被删除)。在Subject 注销后,该Subject的实例被再次认为是匿名的,当然,除了Web 应用程序。

注意:由于在Web 应用程序记住身份往往是依靠Cookies,然而Cookies 只能在Response 被committed 之前被删除,所以强烈建议在调用subject.logout()后立即将终端用户重定向到一个新的视图或页面。

这样能够保证任何与安全相关的Cookies 都能像预期的一样被删除。这是HTTP cookies 的功能限制,而不是Shiro的。

Remembered和Authenticated

Remembered(记住我)

一个记住我的Subject 不是匿名的,是有一个已知的身份ID(也就是subject.getPrincipals()是非空的)。但是这个被记住的身份ID 是在之前的session 中被认证的。如果subject.isRemembered()返回true,则Subject 被认为是被记住的。

Authenticated(已认证)

一个已认证的Subject 是指在当前Session 中被成功地验证过了(也就是说,login方法被调用并且没有抛出异常)。如果subject.isAuthenticated()返回true 则认为Subject 已通过验证。

注意他们是互斥的

Remembered 和Authenticated 是互斥的——若其中一个为真则另一个为假,反之亦然

认证顺序

Step 1:应用程序代码调用Subject.login 方法,传递创建好的包含终端用户的Principals(身份)和Credentials(凭证)的AuthenticationToken 实例。
Step 2:Subject实例,通常是DelegatingSubject(或子类)委托应用程序的SecurityManager通过调用securityManager.login(token)开始真正的验证。
Step3:SubjectManager 接收token 以及简单地委托给内部的Authenticator 实例通过调用authenticator.authenticate(token)。这通常是一个ModularRealmAuthenticator 实例,支持在身份验证中协调一个或多个Realm 实例。
Step 4:如果应用程序中配置了一个以上的Realm,ModularRealmAuthenticator 实例将利用配置好的AuthenticationStrategy 来启动Multi-Realm 认证尝试。在Realms 被身份验证调用之前,期间和以后,AuthenticationStrategy 被调用使其能够对每个Realm 的结果作出反应。
Step 5:每个配置的Realm 用来帮助看它是否支持提交的AuthenticationToken。如果支持,那么支持Realm 的getAuthenticationInfo 方法将会伴随着提交的token 被调用。getAuthenticationInfo 方法有效地代表一个特定Realm 的单一的身份验证尝试。
初识自定义  Realm
这里先来个例子,认识一下:

public class MyRealm extends AuthorizingRealm{

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

String userName = (String) getAvailablePrincipal(principals);

//通过用户名去获得用户的所有资源,并把资源存入info中

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

Set<String> s = new HashSet<String>();

s.add("p1");  s.add("p2"); info.setStringPermissions(s);

Set<String> r = new HashSet<String>();

r.add("r1"); r.add("r2"); info.setRoles(r);

return info;}

protected AuthenticationInfo doGetAuthenticationInfo(

AuthenticationToken token) throws AuthenticationException {

//token中储存着输入的用户名和密码

UsernamePasswordToken upToken = (UsernamePasswordToken)token;

String username = upToken.getUsername();

String password = String.valueOf(upToken.getPassword());

//通常是与数据库中用户名和密码进行比对,这里就省略了

//比对成功则返回info,比对失败则抛出对应信息的异常AuthenticationException

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());

return info;  }}

配置多个Realm

上面的例子可以作为第一个Realm
再复制一份,定义为MyRealm2,在返回user前添加抛出一个例外,表示认真没有通过,如下:

if(username.equals("javass")){

throw new AuthenticationException("MyRealm2 认证失败");

}

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password .toCharArray(),getName());

在配置文件里面添加Realm的定义

myRealm1=cn.javass.hello.MyRealm

myRealm2=cn.javass.hello.MyRealm2

由于有多个realm,一般就需要配置AuthenticationStrategy了,而AuthenticationStrategy是跟Authenticator(认证器)相关的。

配置Authenticator和AuthenticationStrategy

authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator

authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy

authenticator.authenticationStrategy = $authcStrategy

authenticator.realms=$myRealm2,$myRealm1

当然,你可以扩展并实现自己的Authenticator,一般没有必要
最后把Authenticator设置给securityManager

securityManager.authenticator = $authenticator

关于AuthenticationStrategy的配置,有三种:

AtLeastOneSuccessfulStrategy :如果一个(或更多)Realm 验证成功,则整体的尝试被认为是成功的。如果没有一个验证成功,则整体尝试失败。

FirstSuccessfulStrategy 只有第一个成功地验证的Realm 返回的信息将被使用。所有进一步的Realm 将被忽略。如果没有一个验证成功,则整体尝试失败

AllSucessfulStrategy 为了整体的尝试成功,所有配置的Realm 必须验证成功。如果没有一个验证成功,则整体尝试失败。

ModularRealmAuthenticator 默认的是AtLeastOneSuccessfulStrategy

自定义自己的AuthenticationStrategy,通常是扩展自AbstractAuthenticationStrategy,示例如下:

public class MyAuthenticationStrategy extends AbstractAuthenticationStrategy{

public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {

if(realm.getName().equals("myRealm2")){

if(singleRealmInfo==null || singleRealmInfo.getPrincipals()==null){

throw new AuthenticationException("主战认证未通过");

}

}

return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t);

}

}

至于具体覆盖扩展什么方法,需要根据你具体的策略来定。

多个Realm的验证顺序

概述

非常重要的一点是:ModularRealmAuthenticator 将与Realm 实例以迭代的顺序进行交互。

在SecurityManager 中已经配置好了ModularRealmAuthenticator 对Realm实例的访问。当执行一个认证尝试时,它将会遍历该集合,并对每一个支持提交AuthenticationToken 的Realm 调用Realm 的getAuthenticationInfo 方法

隐式排列

当你配置多个realm的时候,处理的顺序默认就是你配置的顺序。

这种情况通常就是只定义了realm,而没有配置securityManager的realms

显示排列

也就是显示的配置securityManager.realms,那么执行的顺序就是你配置该值的realm的顺序。

通常更推荐显示排列。

第四章:Shiro的身份认证(Authentication)相关推荐

  1. Shiro(三) 身份认证源码分析与 MD5 盐值加密

    文章目录 1. 身份认证 2. 身份验证的基本流程 3. 身份验证实现 3.1 在 `login.jsp` 添加登录表单 3.2 添加表单提交的 Controller 3.3 完善 Realm 的身份 ...

  2. SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存

    一.在pom中引入依赖jar包 1 <properties> 2 <shiro.version>1.3.2</shiro.version> 3 </prope ...

  3. Spring Security身份认证Authentication

    文章目录 Authentication(身份认证框架)的架构 SecurityContextHolder AuthenticationManager AbstractAuthenticationPro ...

  4. Spring Boot Shiro视频 - 身份认证准备工作

    [视频 & 交流平台] à SpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008& ...

  5. shiro 方法级别细粒度权限控制_第四章:Shiro的身份认证(Authentication)——深入浅出学Shiro细粒度权限开发框架——私塾在线原创...

    nStep3:SubjectManager 接收token 以及简单地委托给内部的Authenticator 实例通过调用authenticator.authenticate(token).这通常是一 ...

  6. db2 c语言,DB2数据库安全(二)——身份认证

    根据<循序渐进DB2>(牛新庄)第13章内容整理 身份认证(authentication) 1.什么时候进行身份认证 DB2身份认证 控制数据库安全性策略的以下方面:谁有权访问实例或数据库 ...

  7. mysql url认证_Springboot+shiro基于url身份认证和授权认证

    你还不会shiro吗?前奏 shiro核心配置文件(rolesFilter可选). 身份认证 多表登录源如何操作? 授权管理 如何解决界面多角色/资源问题 访问效果 权限管理在日常开发中很重要,所以硬 ...

  8. Shiro身份认证授权原理

    shiro在应用程序中的使用是用Subject为入口的, 最终subject委托给真正的管理者ShiroSecurityMannager Realm是Shiro获得身份认证信息和来源信息的地方(所以这 ...

  9. Springboot学习笔记(四)SpringSecurity.Shiro

    前言: 学习B站UP主狂神说视频笔记整理视频链接 SpringSecurity 安全简介 Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架.它实际上是保护基于sprin ...

最新文章

  1. javascript基础学习(六)
  2. golang中的strings.ContainsRune
  3. C++和Java中类继承同名函数的区分
  4. Linux学习之系统编程篇:孤儿进程和僵尸进程(描述对象都是子进程)
  5. java 入侵 mysql_Java访问数据库Mysql
  6. 技术选型:Sentinel vs Hystrix
  7. 24口光纤配线架 cad块_光纤配线架cad画法
  8. 打印异常堆栈_关于日志打印行号的性能案例
  9. 如何在jsp页面中连接mysql数据库_如何使用JSP访问MySQL数据库
  10. 2017.9.22 middle 失败总结
  11. java常规普氏分析法_人脸对齐:Procrustes analysis 普氏分析
  12. linux python3 装pip,linux 安装pip 和python3(示例代码)
  13. python离线语音识别_python语音识别模块
  14. JasperReport导出Excel锁定行或列
  15. 截取邮箱后缀名,拼接访问邮箱地址
  16. 【科研】浅学Cross-attention?
  17. 别踩白块_前端H5游戏毕设
  18. FPGA错误集锦(二):Output pins are stuck at VCC or GND
  19. 基于微信运动场地预约小程序 毕业设计毕业论文 开题报告和效果图(基于微信小程序毕业设计题目选题课题)
  20. 重庆理工大学计算机学院学概率论,重庆理工大学概率论与数理统计参考附标准答案(a)...

热门文章

  1. RIM微软效仿苹果 将提供免费MobileMe同类服务
  2. 企业的信息化和数字化有什么区别
  3. 微博关注与粉丝业务场景分析
  4. 《实用机器学习》(孙亮 黄倩.著)笔记——第七章 无矩阵分解的基准方法
  5. 取消微软浏览器工具栏的发现按钮
  6. 心系冬奥 翰墨传情 |当代书画名家为奥运加油书画推介展【邓梦洁篇】
  7. 四大组件:Fragment:Fragment 生命周期监控
  8. sylow子群与sylow定理和单群
  9. python例程:《看图猜成语》程序
  10. cad转excel怎么转换?