新版Spring Security6.2案例 - Basic HTTP Authentication

前言:

书接上文,翻译官网Authentication的Username/Password这页,接下来继续翻译basic的这页,因为官网说的都是原理性的,这边一个小案例关于basic http authentication。

Basic Authentication

本节介绍 HTTP 基本身份验证在 Spring Security 中的工作原理。首先,我们看到 WWW-Authenticate 标头被发送回未经身份验证的客户端

上图构建于SecurityFilterChain 图。

1.首先,用户向未授权的资源 /private 发出未经身份验证的请求。

2.Spring Security 的 AuthorizationFilter 通过抛出 AccessDeniedException 来指示未经身份验证的请求被拒绝。

3.由于用户未经过身份验证,因此 ExceptionTranslationFilter 将启动"启动身份验证"。配置的 AuthenticationEntryPoint 是 BasicAuthenticationEntryPoint 的实例,用于发送 WWW-Authenticate 标头。RequestCache 通常是不保存请求的 NullRequestCache,因为客户端能够重播它最初请求的请求。

当客户端收到 WWW-Authenticate 标头时,它知道它应该使用用户名和密码重试。下图显示了正在处理的用户名和密码的流程:

1.当用户提交其用户名和密码时,BasicAuthenticationFilter 会创建一个 UsernamePasswordAuthenticationToken,这是一种通过从 HttpServletRequest 中提取用户名和密码来进行的身份验证。

2.接下来,将 UsernamePasswordAuthenticationToken 传递到 AuthenticationManager 中进行身份验证。AuthenticationManager 外观的详细信息取决于用户信息的存储方式。

3.如果身份验证失败,则定义为"失败",并做如下:

(1)SecurityContextHolder 被清除。

(2)调用 RememberMeServices.loginFail。如果未配置"记住我",则为空操作。请参阅 Javadoc 中的 RememberMeServices 接口。

(3)调用 AuthenticationEntryPoint 以触发再次发送 WWW-Authenticate。请参阅 Javadoc 中的 AuthenticationEntryPoint 接口。

4.如果身份验证成功,则定义为"成功",并做如下:

(1)Authentication身份验证信息则设置在 SecurityContextHolder 上。

(2)调用 RememberMeServices.loginSuccess。如果未配置"记住我",则为空操作。请参阅 Javadoc 中的 RememberMeServices 接口。

(3)BasicAuthenticationFilter 调用 FilterChain.doFilter(request,response) 以继续执行应用程序逻辑的其余部分。请参阅 Javadoc 中的 BasicAuthenticationFilter 类

默认情况下,Spring Security 的 HTTP 基本身份验证支持处于启用状态。但是,一旦提供了任何基于 servlet 的配置,就必须显式提供 HTTP Basic。

以下示例显示了一个最小的显式配置:

java 复制代码
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
	http
		// ...
		.httpBasic(withDefaults());
	return http.build();
}

Basic Authentication例子

项目结构,很简单,maven里面也只有包含3.2spring boot,以及勾选web和security:

代码如下,先把默认表单登录注释掉:

java 复制代码
@Configuration
@EnableWebSecurity
public class MySecurity {


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
        http.authorizeHttpRequests((authorize) -> authorize
                .anyRequest().authenticated()
        )
                .httpBasic(Customizer.withDefaults());
//                .formLogin(Customizer.withDefaults());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(userDetails);
    }

}
java 复制代码
@RestController
public class Login {

    @GetMapping("/private")
    public String doLogin1() {

        return "private";
    }
}

访问localhost:8080/private

就会跳出需要身份验证的对话框,这个浏览器的行为,这是因为服务器的响应的报头里面,有返回

Www-Authenticate: Basic realm="Realm"

在输入完争取用户名密码后,页面会有private,这是因为,在请求头里面有

Authorization: Basic dXNlcjpwYXNzd29yZA==

这个请求头的格式是把用户名密码进行base64编码,中间用冒号隔开,可以

​​

额外说明一点,这个是浏览器生成的访问凭据,一般来说,在浏览器关闭前会一直存在。凭据是保存在浏览器内部的,而不是用的 cookie,localstorage 等存储方式。所以从浏览器工具栏的应用那边删掉cookie方式无法奏效的,但是我试过在隐私设置里面,清除cookie是可以成功的。

参考文献:

《Spring boot官网》

相关推荐
司徒小夜6 分钟前
HTTP与HTTPS杂谈-HTTPS防御了什么
网络·http·https
seabirdssss1 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续1 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0441 小时前
ReAct模式解读
java·ai
轮到我狗叫了2 小时前
牛客.小红的子串牛客.kotori和抽卡牛客.循环汉诺塔牛客.ruby和薯条
java·开发语言·算法
Volunteer Technology3 小时前
三高项目-缓存设计
java·spring·缓存·高并发·高可用·高数据量
栗子~~3 小时前
bat脚本- 将jar 包批量安装到 Maven 本地仓库
java·maven·jar
Mr.Entropy4 小时前
ecplise配置maven插件
java·maven
叙白冲冲4 小时前
tomcat 为啥能一直运行?不像方法那样结束?
java·tomcat
一只游鱼4 小时前
利用keytool实现https协议(生成自签名证书)
网络协议·http·https·keytool