重学SpringBoot3-集成Spring Security(一)

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-集成Spring Security(一)

  • 1. 简介与概念
  • 2. 基础配置
    • 2.1. 添加依赖
    • 2.1 基本认证与授权配置
  • 3. 密码加密
    • 3.1. 如何加密用户密码
    • 3.2. 自定义密码加密器
  • 4. 表单登录与自定义登录页面
    • 4.1. 自定义表单登录配置
    • 4.2. 定义控制器
    • 4.3. 自定义登录界面
    • 4.4. 测试登录
  • 5. 注销
  • 6. 总结

Spring Security 是一个强大、灵活的安全框架,广泛用于保护 Java 应用程序。随着 Spring Boot 3 和 Java 17 的引入,Spring Security 继续增强其功能,为开发者提供了更简化的配置和现代化的安全实践。

本文将详细介绍如何在 Spring Boot 3 中集成 Spring Security,涵盖基本认证、密码加密等核心功能。

1. 简介与概念

Spring Security 提供了基于身份验证(Authentication)和授权(Authorization)的安全模型。身份验证是验证用户身份的过程,而授权则是决定用户是否有权访问资源。

核心组件:

  • SecurityFilterChain:负责定义 HTTP 请求的安全过滤链。
  • UserDetailsService:用于加载用户信息,提供身份验证。
  • PasswordEncoder:处理用户密码的加密与解密。

2. 基础配置

Spring Boot 3 使用自动配置来简化 Spring Security 的集成。但在许多实际场景中,我们需要自定义安全配置,下面介绍基本的 Spring Security 配置步骤。

2.1. 添加依赖

首先,在 pom.xml 中添加 Spring Security 依赖:

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

image-20241013135714903

接着,在 application.yml 中配置安全设置。

2.1 基本认证与授权配置

首先,我们通过创建 SecurityConfig 类来自定义 Spring Security 的配置。该配置类通常需要实现 SecurityFilterChain,Spring Security 通过过滤器链的方式来处理 HTTP 请求。过滤器链由一系列的过滤器 (Filter) 组成,这些过滤器按照配置的顺序依次处理请求。每个过滤器完成特定的安全检查或操作(如身份验证、授权、会话管理等),然后将请求传递给下一个过滤器。

securityfilterchain

示例代码

package com.coderjia.boot313security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @author CoderJia
 * @create 2024/10/13 下午 01:57
 * @Description
 **/
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/").permitAll()  // 公开访问
                        .anyRequest().authenticated()  // 其他接口需认证
                )
                .formLogin(Customizer.withDefaults())
                .httpBasic(Customizer.withDefaults());  // 使用 HTTP Basic 认证
        return http.build();
    }


    @Bean
    public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
        // 创建用户
        UserDetails user = User.builder()
                .username("coderjia")
                .password(passwordEncoder.encode("cj123456"))
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();  // 使用 BCrypt 进行密码加密
    }
}

解释

  1. SecurityFilterChain 定义了所有 HTTP 请求的安全策略。在这里,/ 路径对所有人公开,而其他路径需要用户身份认证。
  2. UserDetailsService 提供了用户的详细信息,包括用户名、密码及角色。在这个例子中,我们创建了一个用户名为 “user” 的用户,密码为 “password”(经过加密处理),并分配了 “USER” 角色,如果不配置,系统则会在日志中输出名为 user 的用户对应的密码:Using generated security password: b9fe7857-97a3-4db7-9602-9e10db56496d
  3. PasswordEncoder 通过 BCryptPasswordEncoder 实现密码加密,以确保用户密码存储时是安全的。
  4. @EnableWebSecurity注解启动 Spring Security 的自动配置,使得应用能够自动集成 Spring Security 提供的安全功能。

3. 密码加密

Spring Security 强烈建议使用加密算法对密码进行加密,防止敏感信息泄露。在 Spring Boot 3 中,BCryptPasswordEncoder 是一种常用的加密方式。它基于 bcrypt 算法,提供了足够的强度和安全性。

3.1. 如何加密用户密码

  • UserDetailsService 中,我们通过 passwordEncoder.encode("password") 对用户密码进行加密。
  • 在身份验证时,Spring Security 会自动使用同样的加密算法进行密码比对。

3.2. 自定义密码加密器

如果需要自定义密码加密算法,可以实现 PasswordEncoder 接口。以下是自定义加密器的简单示例:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(10);  // 设置加密强度
}

在这个示例中,我们为 BCryptPasswordEncoder 提供了加密强度参数,值越大,安全性越高,但加密速度会相对减慢。BCryptPasswordEncoder 的默认实现使用 BCryptPasswordEncoder 的 Javadoc 中提到的强度10。

// Create an encoder with strength 16
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
String result = encoder.encode("myPassword");
System.out.println(encoder.matches("password", result));

或者使用 SpringBoot CLI 对密码进行加密:

$ spring encodepassword password

SpringBoot CLI 加密


4. 表单登录与自定义登录页面

除了 Basic 认证,Spring Security 还支持表单登录。通过 formLogin() 方法,可以启用表单认证,也提供自定义的登录页面。

        http
                .formLogin(Customizer.withDefaults() // 使用默认登录

默认登录界面

4.1. 自定义表单登录配置

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
  			.requestMatchers("/").permitAll()  // 公开访问
            .anyRequest().authenticated()
        )
        .formLogin(form -> form
            .loginPage("/login")  // 自定义登录页面
            .permitAll()  // 登录页面无需认证
        )
        .logout(logout -> logout.permitAll());  // 允许注销
    return http.build();
}

在这里,我们自定义了登录页面 /login,并允许用户访问登录功能而无需认证,提供接口 /index 返回 index.html 页面:

    @GetMapping("/login")
    public String login() {
        return "login";  // 返回名为 "login" 的模板或 HTML 页面
    }

4.2. 定义控制器

package com.coderjia.boot313security.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author CoderJia
 * @create 2024/10/13 下午 02:10
 * @Description
 **/
@Slf4j
@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login";  // 返回名为 "login" 的模板或 HTML 页面
    }


    @GetMapping("/index")
    public String home() {
        log.info("index");
        return "index";  // 返回名为 "index" 的模板或 HTML 页面
    }

    @ResponseBody
    @GetMapping("/admin")
    public String admin() {
        log.info("admin");
        return "欢迎进入管理页面";
    }
}

4.3. 自定义登录界面

提供一个简单的首页页面和登录页,这里使用了 thymeleaf 摸板,详细请参考重学SpringBoot3-集成Thymeleaf:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Main Page</title>
</head>
<body>
<h2>Welcome to my page</span>!</h2>
<a th:href="@{/admin}">访问受限资源</a>
<br/>
<a th:href="@{/logout}">Logout</a>
</body>
</html>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
	<head>
		<title>Please Log In</title>
	</head>
	<body>
		<h1>Please Log In</h1>
		<div th:if="${param.error}">
			Invalid username and password.</div>
		<div th:if="${param.logout}">
			You have been logged out.</div>
		<form th:action="@{/login}" method="post">
			<div>
			<input type="text" name="username" placeholder="Username"/>
			</div>
			<div>
			<input type="password" name="password" placeholder="Password"/>
			</div>
			<input type="submit" value="Log in" />
		</form>
	</body>
</html>

4.4. 测试登录

进入首页,此时不需要登录!

首页


点击 访问受限资源 /admin 要求认证,进入我们自定义的登录页。

自定义登录页

输入设置的用户名和密码之后,认证通过,进入 /admin 页面:

认证通过

5. 注销

有登录,同样也提供了登出,默认情况下,Spring Security 会建立一个 /logout 端点,所以不需要额外的代码。当你包含 spring-boot-starter-security 依赖或使用 @EnableWebSecurity 注解时,Spring Security 将添加其注销支持,并默认响应 GET /logoutPOST /logout

注意,Spring Security 默认开启了防 CSRF 攻击,注销时需要提供 csrf_token,直接调用 GET /logout 会提示 404,只能能通过 POST 请求,

<form th:action="@{/logout}" method="post">
    <button type="submit">Logout</button>
</form>

如果强制要使用 GET 请求,则需要修改成以下配置形式:

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(Customizer.withDefaults())
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/").permitAll()  // 公开访问
                        .anyRequest().authenticated()  // 其他接口需认证
                )
                .formLogin(form -> form
                        .loginPage("/login")
                        .permitAll()
                )
                .logout((logout) -> logout
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                )
                .httpBasic(Customizer.withDefaults());  // 使用 HTTP Basic 认证
        return http.build();
    }

6. 总结

Spring Security 包含的概念很多,本节先简单介绍了其认证功能、用户定义和密码管理,后面会继续介绍其他功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/895153.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

区块链技术在网络安全中的应用研究

摘要&#xff1a; 随着网络技术的快速发展&#xff0c;网络安全问题日益凸显。区块链技术以其去中心化、不可篡改、可追溯等特性&#xff0c;为网络安全提供了新的解决方案。本文深入探讨了区块链技术在网络安全多个领域的应用&#xff0c;包括数据加密与存储、身份认证、网络攻…

Linux 防火墙的开启、关闭、禁用命令

Linux 防火墙的开启、关闭、禁用命令 文章目录 Linux 防火墙的开启、关闭、禁用命令1.设置开机启用防火墙2.设置开机禁用防火墙3.启动防火墙4.关闭防火墙5.检查防火墙状态 1.设置开机启用防火墙 systemctl enable firewalld.service2.设置开机禁用防火墙 systemctl disable f…

算法: 模拟题目练习

文章目录 模拟替换所有的问号提莫攻击Z 字形变换外观数列数青蛙 总结 模拟 替换所有的问号 按照题目的要求写代码即可~ public String modifyString(String ss) {int n ss.length();if (n 1) {return "a";}char[] s ss.toCharArray();for (int i 0; i < n; i…

大数据治理--数据生命周期管理

目录 ​编辑一、数据生命周期阶段 1.1 数据生命周期的定义 1.2 数据生命周期的主要阶段 1.2.1 创建&#xff08;Creation&#xff09; 1.2.2 存储&#xff08;Storage&#xff09; 1.2.3 使用&#xff08;Usage&#xff09; 1.2.4 归档&#xff08;Archiving&#xff09…

概率图模型中的模型推断

文章目录 摘要Abstract1. 概率图模型1.1 模型推断概念1.2 模型推断分类1.2.1 变量消去1.2.2 信念传播1.2.3 近似推断1.2.3.1 采样法1.2.3.1.1 MCMC(马尔可夫链蒙特卡罗)方法 1.2.3.2 变分推断 1.3 话题模型1.3.1 LDA的基本单元1.3.2 话题模型的构成1.3.3 LDA的基本问题1.3.3.1 …

Threejs 实现3D 地图(01)创建基本场景

"d3": "^7.9.0", "three": "^0.169.0", "vue": "^3.5.10" <script setup> import { onMounted,ref } from vue import * as THREE from three import * as d3 from "d3"; //莫开托坐标 矫正地图…

快速上手C语言【下】(非常详细!!!)

目录 1. 指针 1.1 指针是什么 1.2 指针类型 1.2.1 指针-整数 1.2.2 指针解引用 1.3 const修饰 1.4 字符指针 1.5 指针-指针 1.6 二级指针 2. 数组 2.1 定义和初始化 2.2 下标引用操作符[ ] 2.3 二维数组 2.4 终极测试 3. 函数 3.1 声明和定义 3.2 传值调用…

解锁文本数据可视化的无限可能:Wordcloud库全解析

文章目录 **&#x1f31f;解锁文本数据可视化的无限可能&#xff1a;Wordcloud库全解析&#x1f510;**1. **背景介绍**2. **Wordcloud库是什么&#xff1f;**3. **如何安装Wordcloud库&#xff1f;**4. **Wordcloud库的基本函数使用方法**5. **实际应用场景**6. **常见问题及解…

JavaScript:闭包、防抖与节流

一&#xff0c;闭包 1&#xff0c;什么是闭包 闭包是指一个函数和其周围的词法环境(lexical environment)的组合。 换句话说&#xff0c;闭包允许一个函数访问并操作函数外部的变量。 闭包的核心特性: 函数内部可以访问外部函数的变量即使外部函数已经返回&#xff0c;内部…

(AtCoder Beginner Contest 375)B - Traveling Takahashi Problem

&#xff08;AtCoder Beginner Contest 375&#xff09;B - Traveling Takahashi Problem 题目大意 按顺序给定n个点 ( x i , y i ) (x_i,y_i) (xi​,yi​) 求按顺序走过这n个点并回到原点的总距离 任意两点之间的距离是欧几里得距离 思路 按照题意模拟即可&#xff0c;时间…

Cisco软件基础使用

‘地址还未设置’在交换机的CIL中输入enable进入特权模式&#xff0c;输入config t 进入设置 设置进入特权模式的密码和登录的密码 为交换机设置IP地址 未设置地址前显示如下。 下图设置进入特权模式的密码123456 &#xff0c;远程访问登录密码cisco。 exit退一步进入interfa…

cefsharp63.0.3(Chromium 63.0.3239.132)支持H264视频播放-PDF预览 老版本回顾系列体验

一、版本 版本:Cef 63/CefSharp63.0.3/Chromium63.0.3239.132/支持H264/支持PDF预览 支持PDF预览和H264推荐版本 63/79/84/88/100/111/125 <

免费字体二次贩卖;刮刮乐模拟器;小报童 | 生活周刊 #4

Raycast 的两款在线工具 Raycast 公司出品&#xff0c;必属精品&#xff0c;之前的代码转图片工具&#xff0c;交互和颜值都做得很漂亮 现在又新出了一个 图标制作器&#xff0c;一键制作美观好看的图标 猫啃网 没想到像【汇文明朝体】这样免费的字体都被人拿来当成【打字机字…

Gin框架操作指南03:HTML渲染

官方文档地址&#xff08;中文&#xff09;&#xff1a;https://gin-gonic.com/zh-cn/docs/ 注&#xff1a;本教程采用工作区机制&#xff0c;所以一个项目下载了Gin框架&#xff0c;其余项目就无需重复下载&#xff0c;想了解的读者可阅读第一节&#xff1a;Gin操作指南&#…

2024 “源鲁杯“ Round[1] web部分

Disal 打开页面没有有用信息&#xff0c;查看robots.txt发现f1ag.php&#xff0c;访问查看源代码&#xff1a; &#xfeff;<?php show_source(__FILE__); include("flag_is_so_beautiful.php"); $a$_POST[a]; $keypreg_match(/[a-zA-Z]{6}/,$a); $b$_REQUEST[…

【2024最新版】网络安全学习路线-适合入门小白

首先说明&#xff0c;我是一名CTF的web手&#xff0c;这是我自己亲身学习网络安全的路线&#xff0c;希望能够帮到大家&#xff0c;我虽然不是大牛&#xff0c;但我也希望能够帮助一些网安小白找到自己学习的方向&#xff0c;后面有就业的详细安全技术要求&#xff0c;如果真想…

NSSCTF-WEB-easy_eval

目录 前言 正文 思路 序列化构造 后渗透 思路点1:Redis 思路2:蚁剑插件绕过disable_functinons 结尾 作者的其他文章 前言 说是easy,实际很difficult 正文 思路 <?php class A{public $code "";function __call($method,$args){//最后执行命令eval($th…

(AtCoder Beginner Contest 375)A - Seats

&#xff08;AtCoder Beginner Contest 375&#xff09;A - Seats 题目大意 给定一个长度为 N N N的字符串 S S S S S S 只包含"#“和”." 求 "#.#"子串 的出现次数 思路 签到题 O ( N ) O(N) O(N) 模拟即可 代码 #include<iostream> #includ…

ssm配置模式

新版 用Java类&#xff0c;全注解demo案例 1. AppConfig.java (Spring主配置类)package com.example.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.cont…

SpringCloudAlibaba升级手册

目录 1. 版本对照 版本现状 SpringCloud与AlibabaCloud对应版本 Springboot与Elasticsearch版本对应 2. openfeign问题 问题 解决方案 3. Feign请求问题 问题 解决方法 4. Sentinel循环依赖 问题 解决方案 5. bootstrap配置文件不生效 问题 解决方案 6. Nacos的…