写点什么

Spring Security 系列教程 05-- 实现 HTTP 摘要认证

作者:一一哥
  • 2022 年 8 月 30 日
    上海
  • 本文字数:2876 字

    阅读完需:约 9 分钟

Spring Security系列教程05--实现HTTP摘要认证

前言

在前面的 2 个章节中,一一哥 带大家认识了 Spring Security 中的第基本认证与表单认证 2 种认证方式,其中表单认证是 Spring Security 默认的认证方式,也是开发时最常用的认证方式。有的小伙伴会问,不是还有第 3 种认证方式吗?对的,还有第三种摘要认证方式!在本文中,我们来学习了解一下 HTTP 摘要认证。


但是对于摘要认证,我们仅做了解即可,因为这种认证方式仅比基本认证稍微安全一点,开发时用的也不是很多。抱着艺多不压身的心态,我们多了解一点反正也没坏处。

一. HTTP 摘要认证

1. 认证方式

小伙伴们,大家先跟我回顾一下 Spring Security 中的认证方式,有如下 3 种:

  • ①. HTTP 基本认证;

  • ②. Form 表单认证;

  • ③. HTTP 摘要认证;

2. HTTP 摘要认证

那么这个摘要认证是怎么回事呢?我们先来看看它的概念。


HTTP 摘要认证和 HTTP 基本认证一样,也是在 RFC2616 中定义的一种认证方式,它的出现是为了弥补 HTTP 基本认证存在的安全隐患,但该认证方式也并不是很安全。HTTP 摘要认证会使用对通信双方来说都可知的口令进行校验,且最终以密文的形式来传输数据,所以相对于基本认证来说,稍微安全了一些


原来这就是摘要认证啊,懂了?要是还没懂,我们继续往下看摘要认证的认证模型吧。

3. HTTP 摘要认证模型

**HTTP 摘要认证与基本认证类似,基于简单的“挑战-回应”模型。**当我们发起一个未经认证的请求时,服务器会返回一个 401 回应,并给客户端返回与验证相关的参数,期待客户端依据这些参数继续做出回应,从而完成整个验证过程。


这时候你可能会问,服务端会给客户端返回哪些与验证相关的参数呢?挺多的,你往下看!

4. HTTP 摘要认证核心参数

服务端给客户端返回的验证相关参数如下:

  • username: 用户名。

  • password: 用户密码。

  • realm: 认证域,由服务器返回。

  • opaque: 透传字符串,客户端应原样返回。

  • method: 请求的方法。

  • nonce: 由服务器生成的随机字符串,包含过期时间(默认过期时间 300s)和密钥。

  • nc: 即 nonce-count,指请求的次数,用于计数,防止重放攻击。qop 被指定时,nc 也必须被指定。

  • cnonce: 客户端发给服务器的随机字符串,qop 被指定时,cnonce 也必须被指定。

  • qop: 保护级别,客户端根据此参数指定摘要算法。若取值为 auth,则只进行身份验证;若取值为 auth-int,则还需要校验内容完整性,默认的 qop 为 auth。

  • uri: 请求的 uri。

  • response: 客户端根据算法算出的摘要值,这个算法取决于 qop。

  • algorithm: 摘要算法,目前仅支持 MD5。

  • entity-body: 页面实体,非消息实体,仅在 auth-int 中支持。


通常服务器端返回的数据包括 realm、opaque、nonce、qop 等字段,如果客户端需要做出验证回应,就必须按照一定的算法得到一些新的数据并一起返回。在以上各种参数中,对服务器而言,最重要的字段是 nonce;对客户端而言,最重要的字段是 response。


参数好多啊,这谁能记得住啊!说实话,我也记不住,其实对这些参数记几个重要的即可,其余的以后开发时,如果真的用得到,打开 一一哥 的这篇博文,查查是啥意思就好。

二. 摘要认证代码实现

纸上得来终觉浅,绝知此事要躬行!摘要认证的理论知识,我们就了解这么多,还是带大家来实操一把,把代码给搞出来。


注意:我实现这个摘要认证时,结合了数据库查询,这属于后面章节的内容,算是超纲了,如果小伙伴看不懂,到时候请结合后面关于数据库查询的章节一起看!

1. 编写测试接口

我们还是在上个案例的基础上,对项目加以改造,编写 Web 测试接口,具体创建过程参考上文:《Spring Security 系列教程 03--创建 SpringSecurity 项目》

@RestControllerpublic class IndexController {
@GetMapping("/admin/hello") public String helloAdmin() {
return "hello, admin"; }
@GetMapping("/user/hello") public String helloUser() {
return "hello, user"; }
@GetMapping("/visitor/hello") public String helloVisitor() {
return "hello, visitor"; }
}
复制代码

2. 创建 SecurityConfig 配置类

当然,对于 Spring Security 来说,比较关键的就是要有一个 SecurityConfig 配置类,这里比较重要的是配置摘要认证入口端点 DigestAuthenticationEntryPoint。

@EnableWebSecurity(debug = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private DigestAuthenticationEntryPoint digestAuthenticationEntryPoint;
@Autowired private MyUserDetailsService userDetailsService;
//配置认证入口端点,主要是设置认证参数信息 @Bean public DigestAuthenticationEntryPoint digestAuthenticationEntryPoint(){ DigestAuthenticationEntryPoint point=new DigestAuthenticationEntryPoint(); point.setKey("Security Demos"); point.setRealmName("yyg"); point.setNonceValiditySeconds(500); return point; }
public DigestAuthenticationFilter digestAuthenticationFilter(){ DigestAuthenticationFilter filter=new DigestAuthenticationFilter(); filter.setAuthenticationEntryPoint(digestAuthenticationEntryPoint); filter.setUserDetailsService(userDetailsService); return filter; }
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**") .hasRole("ADMIN") .antMatchers("/user/**") .hasRole("USER") .antMatchers("/visitor/**") .permitAll() .anyRequest() .authenticated() .and() .csrf() .disable() //当未认证时访问某些资源,则由该认证入口类来处理. .exceptionHandling() .authenticationEntryPoint(digestAuthenticationEntryPoint) .and() //添加自定义过滤器到过滤器链中 .addFilter(digestAuthenticationFilter()); }
}
复制代码

3. 代码结构

本案例的项目包结构如下,供各位参考。

4. 测试接口

接着来访问一下需要认证的接口,比如/admin/hello 接口,这时候会发现浏览器弹出了一个用户名密码的认证窗口。然后我们在浏览器中可以看到 HTTP 摘要认证信息,realm 是我们自定义的“yyg”,qop 是默认的“auth”方式。


由此可见,此时摘要认证的方式已经生效。

5. HTTP 摘要认证弊端

HTTP 摘要认证与 HTTP 基本认证一样,都是基于 HTTP 层面的认证方式,也不能使用 Session 对象,因而也不支持 Remember-Me 功能。该方式虽然解决了 HTTP 基本认证中以明文传输密码的问题,但并未解决密码明文存储的问题,所以依然有安全隐患,所以在开发中,摘要认证的方式也不怎么使用。


这就是所谓的摘要认证方式,我就给大家介绍这么多,各位对其仅做了解即可。在 3 种认证方式里,我们应该重点掌握表单认证的实现。

发布于: 刚刚阅读数: 4
用户头像

一一哥

关注

还未添加个人签名 2022.08.30 加入

还未添加个人简介

评论

发布
暂无评论
Spring Security系列教程05--实现HTTP摘要认证_HTTP_一一哥_InfoQ写作社区