新版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官网》

相关推荐
雷一言说2 分钟前
Spring AI 2.0 Tool Search:工具多了,只把相关的发给模型
spring
GIoT80109 分钟前
整段 C 段 IP 不能只看 Ping:一套实用的批量检测与分析思路
http
SL_staff13 分钟前
运维救火实战:钉钉API变更致薪资计算中断,如何用可视化逻辑引擎5分钟热修复
java·开源·全栈
猫猫.15335 分钟前
HashTable、HashMap、ConcurrentHashMap 核心区别总结
java·开发语言·java-ee
郭小李1 小时前
spring mvc 工作流程
java·spring·mvc
SL_staff2 小时前
BI大屏嵌入MES的登录态难题:JVS统一账号体系实战解法
java·数据分析·数据可视化
乌暮2 小时前
综合案例:宠物电商系统
java·开发语言·spring·mvc·restful·1024程序员节
VimorphTech2 小时前
一段字幕太长,怎样拆句并安排显示时间?
java·spring boot
万联WANFLOW2 小时前
Kimi K3.1 Pro 接口接入指南:模型选型、费用计算与零数据保留
java·spring boot·python·安全·spring·大模型
织码weavecodes2 小时前
新闻资讯模块设计:内容发布、阅读计数与附件鉴权
java·服务器·数据库