Basic(基本)和Digest(摘要)验证都是web应用中很受欢迎的可选机制。 Basic验证一般用来处理无状态的客户端,它们在每次请求都附带它们的证书。 很常见的用法是把它和基于表单的验证一起使用,这里的应用会同时使用基于浏览器的用户接口和web服务。 然而,basic验证使用原文传送密码,所以应该只通过加密的传输途径发送,比如HTTPS。

9.1. BasicAuthenticationFilter

BasicAuthenticationFilter负责处理通过HTTP头部发送来的basic验证证书。 它可以用来像对待普通用户代理一样(比如IE和Navigator)认证由Spring远程协议的调用(比如Hessian和Burlap)。 HTTP基本认证的执行标准定义在RFC 1945,11章,BasicAuthenticationFilter符合这个RFC。 基本认证是一个极具吸引力的认证方法,因为它在用户代理发布很广泛,
实现也特别简单(只需要对username:password进行Base64编码,再放到HTTP头部里)。

9.1.1. 配置

要实现HTTP基本认证,要先在过滤器链里定义BasicAuthenticationFilter。 还要在application context里定义BasicAuthenticationFilter和协作的类:

<bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean> <bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName" value="Name Of Your Realm"/>
</bean>

配置好的AuthenticationManager会处理每个认证请求。 如果认证失败,配置好的AuthenticationEntryPoint会用来重试认证过程。 通常你会使用BasicAuthenticationEntryPoint,它会返回一个401响应,使用对应的头部重试HTTP基本验证。 如果验证成功,就把得到的Authentication对象放到SecurityContextHolder里。

如果认证事件成功,或者因为HTTP头部没有包含支持的认证请求所以没有进行认证,过滤器链会像通常一样继续下去。 唯一打断过滤器的情况是在认证失败并调用AuthenticationEntryPoint的时候,向上面段落里讨论的那样。

9.2. DigestAuthenticationFilter

Spring Security提供了一个 DigestAuthenticationFilter,它可以处理HTTP头部中的摘要认证证书。 摘要认证在尝试着解决许多基本认证的缺陷,特别是保证不会通过纯文本发送证书。 许多用户支持摘要式认证,包括FireFox和IE。 HTTP摘要式认证的执行标准定义在RFC 2617,它是对RFC 2069这个早期摘要式认证标准的更新。 Spring Security DigestAuthenticationFilter会保证"auth"的安全质量(qop),它订明在RFC
2617中,并与RFC 2069提供了兼容。 如果你需要使用没有加密的HTTP(比如没有TLS/HTTP),还希望认证达到最大的安全性的时候,摘要式认证便具有很高吸引力。 事实上,摘要式认证是WebDAV协议的强制性要求,写在RFC 2518的17.1章,所以我们应该期望看到更多的代替基本认证。

摘要式认证,是表单认证,基本认证和摘要式认证中最安全的选择,不过更安全也意味着更复杂的用户代理实现。 摘要式认证的中心是一个“nonce”。 这是由服务器生成的一个值。 Spring Security的nonce采用下面的格式:

                base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))

                expirationTime:   The date and time when the nonce expires, expressed in milliseconds
key: A private key to prevent modification of the nonce token

这个DigestAuthenticationEntryPoint有一个属性,通过指定一个key来生成nonce标志,通过nonceValiditySeconds属性来决定过期时间(默认300,等于5分钟)。 只要nonce是有效的,摘要就会通过串联字符串计算出来,包括用户名,密码,nonce,请求的URI,一个客户端生成nonce(仅仅是一个随机值,用户代理每个请求生成一个),realm名称等等,然后执行一次MD5散列。
服务器和用户代理都要执行这个摘要计算,如果他们包含的值不同(比如密码),就会生成不同的散列码。 在Spring Security的实现中,如果服务器生成的nonce已经过期(但是摘要还是有效),DigestAuthenticationEntryPoint会发送一个"stale=true"头信息。 这告诉用户代理,这里不再需要打扰用户(像是密码和用户其他都是正确的),只是简单尝试使用一个新nonce。

DigestAuthenticationEntryPoint的 nonceValiditySeconds参数,会作为一个适当的值依附在你的程序上。 对安全要求很高的用户应该注意,一个被拦截的认证头部可以用来假冒主体,直到nonce达到expirationTime。 在选择合适的配置的时候,这是一个必须考虑到的关键性条件,但是在对安全性要求很高的程序里,第一次请求都会首先运行在TLS/HTTPS之上。

因为摘要式认证需要更复杂的实现,这里常常有用户代理的问题。 比如,IE不能在同一个会话的请求进程里阻止"透明"标志。 因此Spring Security把所有状态信息都概括到"nonce"标记里。 在我们的测试中,Spring Security在FireFox和IE里都可以工作,正确的处理nonce超时等等。

9.2.1. Configuration

现在我们重新看一下理论,让我们看看如何使用它。 为了实现HTTP摘要认证,必须在过滤器链里定义DigestAuthenticationFilter。 application context还需要定义DigestAuthenticationFilter和它需要的合作伙伴:

<bean id="digestnFilter" class=
"org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
<property name="userDetailsService" ref="jdbcDaoImpl"/>
<property name="authenticationEntryPoint" ref="digestEntryPoint"/>
<property name="userCache" ref="userCache"/>
</bean> <bean id="digestEntryPoint" class=
"org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
<property name="realmName" value="Contacts Realm via Digest Authentication"/>
<property name="key" value="acegi"/>
<property name="nonceValiditySeconds" value="10"/>
</bean>

需要配置一个UserDetailsService,因为 DigestAuthenticationFilter必须直接访问用户的纯文本密码。 如果你在DAO中使用编码过的密码,摘要式认证就没法工作。 DAO合作者,与UserCache一起,通常使用DaoAuthenticationProvider直接共享。
这个AuthenticationEntryPoint属性必须是DigestAuthenticationEntryPoint,这样DigestAuthenticationFilter可以在进行摘要计算时获得正确的realmNamekey

BasicAuthenticationFilter一样,如果认证成功,会把Authentication请求标记放到SecurityContextHolder中。 如果认证事件成功,或者认证不需要执行,因为HTTP头部没有包含摘要认证请求,过滤器链会正常继续。 过滤器链中断的唯一情况是,如果认证失败,就会像上面讨论的那样调用AuthenticationEntryPoint

摘要式认证的RFC要求附加功能范围,来更好的提升安全性。 比如,nonce可以在每次请求的时候变换。 但是,Spring Security的设计思路是最小复杂性的实现(毫无疑问,用户代理会出现不兼容),也避免保存服务器端的状态。 如果你想研究这些功能的更多细节,我们推荐你看一下RFC 2617。 像我们知道的那样,Spring Security实现类遵守了RFC的最低标准。

Spring Http Basic(基本)和Digest(摘要)验证的更多相关文章

  1. Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结

    Atitit HTTP认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结 1.1. 最广泛使用的是基本验证 ( ...

  2. spring(7)--注解式控制器的数据验证、类型转换及格式化

    7.1.简介 在编写可视化界面项目时,我们通常需要对数据进行类型转换.验证及格式化. 一.在Spring3之前,我们使用如下架构进行类型转换.验证及格式化: 流程: ①:类型转换:首先调用Proper ...

  3. EasyDarwin开源流媒体服务器支持basic基本认证和digest摘要认证解析

    本文转自EasyDarwin开源团队成员ss的博客:http://blog.csdn.net/ss00_2012/article/details/52262621 RTSP认证作为RTSP标准协议的一 ...

  4. EasyDarwin开源流媒体服务器支持basic基本认证和digest摘要自定义认证

    本文转自EasyDarwin开源团队成员的博客:http://blog.csdn.net/ss00_2012/article/details/52330838 在前面<EasyDarwin拉流支 ...

  5. Spring Security框架下Restful Token的验证方案

    项目使用Restful的规范,权限内容的访问,考虑使用Token验证的权限解决方案. 验证方案(简要概括): 首先,用户需要登陆,成功登陆后返回一个Token串: 然后用户访问有权限的内容时需要上传T ...

  6. php Basic HTTP与Digest HTTP 应用

    Basic HTTP 认证范例 <?php //Basic HTTP 认证 if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authen ...

  7. Spring中使用Jcaptcha实现校验码验证

    本文将使用Jcaptcha实现校验码验证,并演示在Spring/SpringMVC环境下的使用方法. 1. maven依赖 <dependency> <groupId>com. ...

  8. spring mvc 使用jsr-303进行表单验证的方法介绍

    源代码来源:http://howtodoinjava.com/spring/spring-mvc/spring-bean-validation-example-with-jsr-303-annotat ...

  9. spring AOP 和自定义注解进行身份验证

    一个SSH的项目(springmvc+hibernate),需要提供接口给app使用.首先考虑的就是权限问题,app要遵循极简模式,部分内容无需验证,用过滤器不能解决某些无需验证的方法 所以最终选择用 ...

随机推荐

  1. Android系统开发 编译系统签名的APP

    前言 一般情况下,我们使用的签名都是自己生成的Java签名来编译APP. 但是,如果需要开发一些特定设备的APP(对权限有更高的要求,需求一些系统基本的权限,比如让APP可以控制设备的休眠),那就需要 ...

  2. jquery高级编程学习

    jquery高级编程 第1章.jQuery入门 类型检查 对象 类型检查表达式 String typeof object === "string" Number typeof ob ...

  3. nodejs与websocket模拟简单的聊天室

    nodejs与websocket模拟简单的聊天室 server.js const http = require('http') const fs = require('fs') var userip ...

  4. day 80 Vue学习一之vue初识

    Vue学习一之vue初识   本节目录 一 Vue初识 二 ES6的基本语法 三 Vue的基本用法 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 vue初识 vue称为渐进式js框架 ...

  5. 一个因为系统字号设置导致的rem计算渲染异常问题

    测试同学突然拿着一部手机过来说,H5渲染各个元素都变大了,有些元素撑出了屏幕外面. 本来以为是某个Webview的渲染兼容问题,结果发现所有的浏览器都这样. 莫名其妙,隐约感觉是 rem计算出了问题, ...

  6. PAT甲级——A1134 Vertex Cover【25】

    A vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at le ...

  7. 无法启动此程序,因此计算机中丢失VCRUNTIME140.dll。

    在mysql-8.0.12-winx64创建data文件夹 在cmd终端 初始化 MYSQL: mysqld --initialize-insecure MySQL加入Windows服务:mysqld ...

  8. 宇宙最强 IDE:VS 2019 正式发布

    作者:局长 来源:www.oschina.net/news/105629/ 如约而至,微软已于今天推出 Visual Studio 2019 正式版,一同发布的还有 Visual Studio 201 ...

  9. 6_1.springboot2.x整合JDBC与数据源配置原理解析

    1.引言 对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合 Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置.引入各种xxxTemplate,x ...

  10. ERROR 1839 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_MODE = ON

    从cdb上dump一个库结构,准备与本地结构做对比(可以直接compare,但速度贼慢).使用dump脚本在本地创建的时候报错 -- 导出指定库的结构 shell> mysqldump -hxx ...