digest认证比form-login和http-basic更安全的一种认证方式,尤其适用于不能使用https协议的场景。它与http-basic一样,都是不基于session的无状态认证方式。
因为digest不包含在命名空间中,所以我们需要配置额外的过滤器和验证入口。
<beans:bean id="digestProcessingFilter" class="org.springframework.security.ui.digestauth.DigestProcessingFilter"> <custom-filter position="BASIC_PROCESSING_FILTER" /> <beans:property name="authenticationEntryPoint" ref="digestProcessingFilterEntryPoint"/> <beans:property name="userDetailsService" ref="org.springframework.security.userdetails.memory.InMemoryDaoImpl"/> </beans:bean> <beans:bean id="digestProcessingFilterEntryPoint" class="org.springframework.security.ui.digestauth.DigestProcessingFilterEntryPoint"> <beans:property name="realmName" value="springsecurity"/> <beans:property name="key" value="changeIt"/> </beans:bean>
然后记得删除auto-config="true",去除默认的form-login和http-basic认证,并添加对验证入口的引用。
<http auto-config="true" entry-point-ref="digestProcessingFilterEntryPoint"> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/" access="ROLE_USER" /> </http>
现在我们访问系统时,不会再进入之前的登录页面,而是会显示浏览器原生的登录对话框。
登录成功之后,我们可以在HTTP请求头部看到basic验证所需的属性Authorization。
最后需要注意的是,因为digest认证不使用session,所以无法与rememberMe功用。
如果希望自己编写客户端进行digest认证,可以参考RFC 2617,它是对RFC 2069这个早期摘要式认证标准的更新。
在HTTP请求头中将包含这样一个Authorization,它包含了username, realm, nonce, uri, responseDigest, qop, nc和cnonce八个部分。其中nonce是digest认证的中心,它的组成结构如下所示:
base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))
如果服务器生成的nonce已经过期(但是摘要还是有效),DigestProcessingFilterEntryPoint会发送一个"stale=true"头信息。 这告诉用户代理,这里不再需要打扰用户(像是密码和用户其他都是正确的),只是简单尝试使用一个新nonce。
实例在ch112。