您的位置:首页 > 理论基础 > 计算机网络

Spring Http Basic(基本)和Digest(摘要)验证

2016-01-07 12:46 525 查看
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),还希望认证达到最大的安全性的时候,摘要式认证便具有很高吸引力。 事实上,摘要式认证是WebD***协议的强制性要求,写在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
可以在进行摘要计算时获得正确的
realmName
key


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


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