本文主要是介绍springboot依靠security实现digest认证的实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《springboot依靠security实现digest认证的实践》HTTP摘要认证通过加密参数(如nonce、response)验证身份,避免明文传输,但存在密码存储风险,相比基本认证更安全,却因...
概述
HTTP 摘要认证使用对通信双方都可知的口令进行校验,最终的传输数据并非明文形式。
HTTP 摘要基本认证意在解决 HTTP 基本认证存在的大部分严重漏洞,但不应将其认为是Web安全的最终解决方案。
参数
HTTP摘要认证的回应与HTTP基本认证相比要复杂得多,下面看看HTTP摘要认证中涉及的一些参数:
username:用户名。password:用户密码。realm:认证域,由服务器返回。opaque:透传字符串,客户端应原样返回。methjavascriptod:请求的方法。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.SpringBootAppliandroidcation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author gzb */ @RestphpController @SpringBootApplication public class Digest1Application { public static void main(String[] args) { SpringApplication.runphp(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 implandroidements 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
查看请求数据:

总结
这篇关于springboot依靠security实现digest认证的实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!