springboot依靠security实现digest认证的实践

 更新时间:2025年09月28日 15:15:39   作者:knight郭志斌  
HTTP摘要认证通过加密参数(如nonce、response)验证身份,避免明文传输,但存在密码存储风险,相比基本认证更安全,却因实现复杂且不支持Remember-me,未被广泛采用,测试案例显示其工作流程

概述

HTTP 摘要认证使用对通信双方都可知的口令进行校验,最终的传输数据并非明文形式。

HTTP 摘要基本认证意在解决 HTTP 基本认证存在的大部分严重漏洞,但不应将其认为是Web安全的最终解决方案。

参数

HTTP摘要认证的回应与HTTP基本认证相比要复杂得多,下面看看HTTP摘要认证中涉及的一些参数:

  • username:用户名。
  • password:用户密码。
  • realm:认证域,由服务器返回。
  • opaque:透传字符串,客户端应原样返回。
  • method:请求的方法。
  • nonce:由服务器生成的随机字符串。
  • nc:即nonce-count,指请求的次数,用于计数,防止重放攻击。qop被指定时,nc也必须被指定。
  • cnonce:客户端发给服务器的随机字符串,qop被指定时,cnonce也必须被指定。
  • qop:保护级别,客户端根据此参数指定摘要算法。若取值为auth,则只进行身份验证;若取值为auth-int,则还需要校验内容完整性。
  • uri:请求的uri。
  • response:客户端根据算法算出的摘要值。
  • algorithm:摘要算法,目前仅支持MD5。
  • entity-body:页面实体,非消息实体,仅在auth-int中支持。

通常服务器携带的数据包括realm、opaque、nonce、qop等字段,如果客户端需要做出验证回应,就必须按照一定的算法计算得到一些新的数据并一起返回。

总结:

  • HTTP摘要认证与HTTP基本认证一样,都是基于HTTP层面的认证方式,不使用session,因而不支持Remember-me。
  • 虽然解决了HTTP基本认证密码明文传输的问题,但并未解决密码明文存储的问题,依然存在安全隐患。
  • HTTP 摘要认证与 HTTP 基本认证相比,仅仅在非加密的传输层中有安全优势,但是其相对复杂的实现流程,使得它并不能成为一种被广泛使用的认证方式。

Demo

pom.xml依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 测试包,当我们使用 mvn package 的时候该包并不会被打入,因为它的生命周期只在 test 之内-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

Digest1Application.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author gzb
 */
@RestController
@SpringBootApplication
public class Digest1Application {

    public static void main(String[] args) {
        SpringApplication.run(Digest1Application.class, args);
    }

    @GetMapping("/demo1")
    public String demo1() {
        return "Hello battcn";
    }

}

MyPasswordEncoder.java

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @author gzb
 * @date 2021/10/1315:06
 */
@Component
public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence charSequence) {
        return charSequence.toString();
    }

    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return s.equals(charSequence.toString());
    }
}

WebSecurityConfig.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;

/**
 * @author gzb
 * @date 2021/10/1313:41
 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DigestAuthenticationEntryPoint myDigestEntryPoint;
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public DigestAuthenticationEntryPoint digestEntryPoint() {
        DigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new DigestAuthenticationEntryPoint();
        digestAuthenticationEntryPoint.setKey("https://blog.csdn.net/zhanwuguo8346");
        digestAuthenticationEntryPoint.setRealmName("spring security");
        digestAuthenticationEntryPoint.setNonceValiditySeconds(500);
        return digestAuthenticationEntryPoint;
    }

    public DigestAuthenticationFilter digestAuthenticationFilter() {
        DigestAuthenticationFilter filter = new DigestAuthenticationFilter();
        filter.setAuthenticationEntryPoint(myDigestEntryPoint);
        filter.setUserDetailsService(userDetailsService);
        return filter;
    }

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(myDigestEntryPoint)
                .and()
                .addFilter(digestAuthenticationFilter());
    }
}

application.properties

server.port=9090
server.servlet.context-path=/ditest

spring.security.user.name=name
spring.security.user.password=password

测试

  • 浏览器F12打开开发者界面
  • 启动项目,浏览器访问:http://localhost:9090/ditest/demo1
  • 输入用户名、密码:name、password
  • 界面返回:Hello battcn

查看请求数据:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Idea中Springboot热部署无效问题解决

    Idea中Springboot热部署无效问题解决

    这篇文章主要介绍了Idea中Springboot热部署无效问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • App登陆java后台处理和用户权限验证

    App登陆java后台处理和用户权限验证

    这篇文章主要为大家详细介绍了App登陆java后台处理和用户权限验证,感兴趣的朋友可以参考一下
    2016-06-06
  • java代码mqtt接收发送消息方式

    java代码mqtt接收发送消息方式

    这篇文章主要介绍了java代码mqtt接收发送消息方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java中HashMap和Hashtable的区别浅析

    Java中HashMap和Hashtable的区别浅析

    这篇文章主要介绍了Java中HashMap和Hashtable的区别浅析,本文总结了6条它们之间的不同之处,需要的朋友可以参考下
    2015-03-03
  • SpringBoot2升级到SpringBoot3后Nacos热更新失效问题分析

    SpringBoot2升级到SpringBoot3后Nacos热更新失效问题分析

    SpringBoot升级至SpringBoot3后Nacos配置热更新失效的原因原因及解决方法,本文详细分析了问题产生的原因原因原因并提供了具体解决方案,包括移除spring-cloud-starter-bootstrap依赖、统一配置文件格式及注解配置等确保配置热更新功能正常运作,需要的朋友可以参考下
    2026-05-05
  • Spring Cloud @EnableFeignClients注解的属性字段basePacka详解

    Spring Cloud @EnableFeignClients注解的属性字段basePacka详解

    这篇文章主要介绍了Spring Cloud @EnableFeignClients注解的属性字段basePacka详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringDataJpa:JpaRepository增删改查操作

    SpringDataJpa:JpaRepository增删改查操作

    这篇文章主要介绍了SpringDataJpa:JpaRepository增删改查操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 深入了解Java线程池的原理使用及性能优化

    深入了解Java线程池的原理使用及性能优化

    JAVA线程池是一种管理和复用线程资源的机制,可以提高程序的效率和响应速度。本文将介绍线程池的原理、使用方法和性能优化技巧,帮助读者深入了解和应用JAVA线程池
    2023-04-04
  • Java中CRUD的快速实现方法

    Java中CRUD的快速实现方法

    Java中的CRUD(Create、Read、Update、Delete)操作是数据持久化的基础操作,通常用于与数据库交互,这篇文章主要介绍了Java CRUD的快速实现,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2025-10-10
  • java实现简单的搜索引擎

    java实现简单的搜索引擎

    这篇文章主要为大家详细介绍了java实现简单的搜索引擎的相关资料,需要的朋友可以参考下
    2016-02-02

最新评论