【Spring Security】 Spring Security 使用案例详细教程

文章目录

    • 一、Spring Security 入门案例
      • 1.1 导入依赖
      • 1.2 运行项目
      • 1.3 测试项目
    • 二、Spring Security 简单实现案例
      • 2.1 导入依赖
      • 2.2 配置 Spring Security
      • 2.3 创建访问资源
      • 2.4 测试身份验证和授权
    • 参考资料

一、Spring Security 入门案例

入门案例具体教程查看 Hello Spring Security :: Spring Security

1.1 导入依赖

根据 Getting Spring Security ,在 pom.xml 中导入 Spring Security 的相关依赖:

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

Spring Security 会在项目中启用 默认的身份验证和安全机制。无需额外的配置,就可以体验基本的用户认证。

1.2 运行项目

在不编写代码的情况下,Spring Boot 应用后,可以看到控制台输出日志:

Using generated security password: ed803299-ccd3-4ee0-8160-652eed542814This generated password is for development use only. Your security configuration must be updated before running your application in production.

在没有配置 Authentication 的情况下,Spring Security 默认创建一个用户名为 user 的用户,并生成随机密码。该密码只用于开发环境,生产环境应自定义更安全的认证方式。

1.3 测试项目

测试 Basic HTTP Authentication 。

(1)未验证身份的请求

通过未验证身份直接访问受保护的路径时,Spring Security 会拒绝访问,并返回 401 Unauthorized 状态码:

$ curl -i http://localhost:8080/some/path
HTTP/1.1 401
Set-Cookie: JSESSIONID=598AEA648FB18B56CB28ACC1234AC174; Path=/; HttpOnly
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Thu, 07 Nov 2024 03:16:39 GMT

curl -i http://localhost:8080/admin/secure

curl -i -u user1:123456 http://localhost:8080/admin/secure

(2) 验证身份的请求

提供用户名 user 和生成的密码后,可以成功通过身份验证。若请求的资源不存在,Spring Boot 将返回 404 Not Found

$ curl -i -u user:ed803299-ccd3-4ee0-8160-652eed542814 http://localhost:8080/some/path
HTTP/1.1 404
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 07 Nov 2024 03:22:50 GMT{"timestamp":"2024-11-07T03:22:50.775+00:00","status":404,"error":"Not Found","path":"/some/path"}

二、Spring Security 简单实现案例

本案例展示了如何使用 Spring Security 实现以下功能:

  1. 配置自定义用户名和密码。
  2. 基于角色的授权控制

2.1 导入依赖

根据 Getting Spring Security ,在 pom.xml 中导入 Spring Security 的相关依赖:

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

2.2 配置 Spring Security

根据 Java Configuration :: Spring Security,可以通过 Java 配置来自定义用户信息。同时,通过 Authorize HttpServletRequests 来定义不同角色的访问控制规则。

/*** Spring Security 配置类* <p>*     基于角色的权限控制使用案例* </p>** @author zouhu* @data 2024-11-07 11:46*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig{/*** 配置自定义用户,并给每个用户分配角色*/@Beanprotected UserDetailsManager userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withUsername("user").password("{noop}123456")    // 使用 {noop} 前缀表示明文密码,仅用于开发和测试环境,生产环境推荐使用其他加密方式(如 BCrypt)。// .roles("USER")               // 分配 USER 角色,角色会自动添加前缀 ROLE_.authorities("USER")         // 使用 authorities 而不是 roles,角色不会添加前缀.build());manager.createUser(User.withUsername("admin").password("{noop}admin123456")// .roles("ADMIN")    // 分配 ADMIN 角色,角色会自动添加前缀 ROLE_.authorities("ADMIN").build());return manager;}/*** 配置角色的访问规则*/@Beanpublic SecurityFilterChain web(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorize) -> {// 管理员角色可访问的资源authorize.requestMatchers("/admin/**").hasAuthority("ADMIN");// 用户角色可访问的资源(注释掉的部分,如果未来需要启用可以取消注释)authorize.requestMatchers("/user/**").hasAuthority("USER");// 允许所有角色访问的资源authorize.requestMatchers("/").permitAll();// 其他所有请求都需要身份验证authorize.anyRequest().authenticated();}).formLogin(withDefaults())  // 启用表单登录,默认登录页面为 /login.httpBasic(withDefaults()); // 启用 HTTP Basic Authenticationreturn http.build();}
}

2.3 创建访问资源

@RestController
public class DemoController {@GetMapping("/user/secure")public String userAccess() {return "Hello User!";}@GetMapping("/admin/secure")public String adminAccess() {return "Hello Admin!";}@RequestMapping("/")public String home() {return "Welcome to the Home Page!";}
}

2.4 测试身份验证和授权

(1) 验证角色的权限

使用 @WithMockUser 注解来模拟不同角色的用户进行权限验证。

@SpringBootTest
@AutoConfigureMockMvc
class WebSecurityConfigTest {@Autowiredprivate MockMvc mvc;/***  测试未认证用户访问主页和受限资源*/// @WithMockUser  // 未加 @WithMockUser 表示请求由未认证用户发出@Testvoid Unauthenticated() throws Exception {this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Welcome to the Home Page!")); // 预期返回 200 OKthis.mvc.perform(get("/admin/secure")).andExpect(status().isUnauthorized())  // 预期返回 401 Unauthorized.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));}/*** 测试默认用户(无特殊权限)的访问*/@WithMockUser  // 模拟一个没有设置特定权限的默认用户@Testvoid NotAuthorityUser() throws Exception {this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Welcome to the Home Page!")); // 预期返回 200 OKthis.mvc.perform(get("/user/secure")).andExpect(status().isForbidden()); // 预期返回 403 Forbidden}/***  测试具有 USER 权限的用户访问受限资源*/@WithMockUser(authorities = "USER")@Testvoid UserAuthority() throws Exception {this.mvc.perform(get("/user/secure")).andExpect(status().isOk()).andExpect(content().string("Hello User!"));  // 预期返回 200 OKthis.mvc.perform(get("/admin/secure")).andExpect(status().isForbidden());  // 预期返回  403 Forbidden}/***  测试具有 ADMIN 权限的用户访问受限资源*/@WithMockUser(authorities = "ADMIN")@Testvoid AdminAuthority() throws Exception {this.mvc.perform(get("/user/secure")).andExpect(status().isForbidden()); // 预期返回 403 Forbiddenthis.mvc.perform(get("/admin/secure")).andExpect(status().isOk()).andExpect(content().string("Hello Admin!"));  // 预期返回 200 OK}
}

(2)验证用户是否能访问

使用 curl 命令行工具模拟 HTTP 请求,验证不同用户权限。

# 未认证用户访问受限资源
$ curl -i  http://localhost:8080/admin/secure
HTTP/1.1 401
Set-Cookie: JSESSIONID=7C9FAE078D4DD87F777A6AA4836D12C8; Path=/; HttpOnly
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Thu, 07 Nov 2024 09:21:45 GMT# 使用管理员账户访问受限资源
$  curl -i -u admin:admin123456 http://localhost:8080/admin/secure
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/plain;charset=UTF-8
Content-Length: 12
Date: Thu, 07 Nov 2024 09:22:19 GMTHello Admin!

参考资料

Java Configuration :: Spring Security

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Aop+自定义注解实现数据字典映射

数据字典 Web项目开发中&#xff0c;字典表的一般都会存在&#xff0c;主要用来给整个系统提供基础服务。 比如男女性别的类型可以使用0和1来进行表示&#xff0c;在存储数据和查询数据的时候&#xff0c;就可以使用字典表中的数据进行翻译处理。 再比如之前做的一个项目中宠物…

Cursor的chat与composer的使用体验分享

经过一段时间的试用&#xff0c;下面对 Composer 与 Chat 的使用差别进行总结&#xff1a; 一、长文本及程序文件处理方面 Composer 在处理长文本时表现较为稳定&#xff0c;可以对长文进行更改而不会出现内容丢失的情况。而 Chat 在更改长的程序文件时&#xff0c;有时会删除…

小北的字节跳动青训营与调用模型:调用模型:OpenAI API vs 微调开源Llama2/ChatGLM(持续更新中~~~)

前言 最近&#xff0c;字节跳动的青训营再次扬帆起航&#xff0c;作为第二次参与其中的小北&#xff0c;深感荣幸能借此机会为那些尚未了解青训营的友友们带来一些详细介绍。青训营不仅是一个技术学习与成长的摇篮&#xff0c;更是一个连接未来与梦想的桥梁~ 小北的青训营 X M…

Axure设计之三级联动选择器教程(中继器)

使用Axure设计三级联动选择器&#xff08;如省市区选择器&#xff09;时&#xff0c;可以利用中继器的数据存储和动态交互功能来实现。下面介绍中继器三级联动选择器设计的教程&#xff1a; 一、效果展示&#xff1a; 1、在三级联动选择器中&#xff0c;首先选择省份&#xff…

七次课掌握 Photoshop:选区与抠图

Photoshop 是一门选择的艺术。Photoshop 提供了多种工具和方法来创建选区&#xff0c;适用于不同的场景和需求。 理解和熟练使用这些工具&#xff0c;是提高图像处理能力的关键。 ◆ ◆ ◆ 选区方法与操作 一、创建选区的工具和命令 1、选区工具 &#xff08;1&#xff09;选…

智慧商城项目-VUE2

实现效果 项目收获 通过本项目的练习&#xff0c;可以掌握以下内容&#xff1a; 创建项目 ##基本创建 基于 VueCli 自定义创建项目架子,并对相关的配置进行选择 vue create demo-shopping调整目录 删除文件 删除初始化的一些默认文件 src/assets/logo.pngsrc/components…

Java | Leetcode Java题解之第546题移除盒子

题目&#xff1a; 题解&#xff1a; class Solution {int[][][] dp;public int removeBoxes(int[] boxes) {int length boxes.length;dp new int[length][length][length];return calculatePoints(boxes, 0, length - 1, 0);}public int calculatePoints(int[] boxes, int l…

PDF多功能工具箱 PDF Shaper v14.6

如今对PDF处理的软件很多都是只是单一的功能。PDF Shaper给你完全不同的体验&#xff0c;因为PDF Shaper是一款免费的PDF工具集合的软件。有了PDF Shaper&#xff0c;你以后再也不用下载其他处理PDF的软件了。PDF Shaper的功能有&#xff1a;合并&#xff0c;分割&#xff0c;加…

论文阅读--捍卫基于激光雷达视野范围的三维目标检测

目前存在的问题&#xff1a; 常用的体素化或鸟瞰图&#xff08;BEV&#xff09;表示相比&#xff0c;范围视图表示更紧凑且没有量化误差&#xff0c;但其在目标检测方面的性能很大程度上落后于体素化或 BEV 。范围视图尺度变化的挑战2D 图像不同&#xff0c;虽然距离图像的卷积…

使用匿名管道时出现程序一直运行问题

父进程创建两个子进程&#xff0c;父子进程之间利用管道进行通信。要求能显示父进程、子进程各自的信息&#xff0c;体现通信效果。(源程序pipe_1.c) 一开始&#xff0c;我忘了初始化pipe,很傻*的直接把fd当管道使&#xff0c;出现了儿子喊爸爸"i am your father."的…

【笔记】开关电源变压器设计 - 工作磁通的选择原则

变压器设计中有一个重要的输入参数&#xff0c;是选定电路工作的磁路参数。涉及到磁场的上下震荡最高幅度。如上图所示。磁场的方向有正负&#xff0c;所以如果电流在越过零点震荡&#xff0c;只考虑半周来和Bs或者Bmax比对即可。Bs,Bmax与特定材料有关。材料给出的最大Bmax,或…

一文了解Android本地广播

在 Android 开发中&#xff0c;本地广播&#xff08;Local Broadcast&#xff09;是一种轻量级的通信机制&#xff0c;主要用于在同一应用进程内的不同组件之间传递消息&#xff0c;而无需通过系统的全局广播机制。这种方法既可以提高安全性&#xff08;因为广播仅在应用内传播…

Spark本地模式安装

【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 《Spark SQL大数据分析快速上手》【摘要 书评 试读】- 京东图书 大数据与数据分析_夏天又到了的博客-CSDN博客 Hadoop完全分布式环境搭建步骤-CSDN博客,前置环境安装参看此博文 Spark本地模式安装 Spark本地模式的安…

SpringSecurity6+OAuth2.0 从入门到熟练使用

文章目录 简介1、快速入门1.1 准备工作我们先要搭建一个SpringBoot工程① 创建工程 添加依赖② 创建启动类③ 创建Controller1.2 引入SpringSecurity2、 认证2.1 登录校验流程2.2 原理分析2.2.1 SpringSecurity完整流程2.2.2 认证流程详解概念速查:2.3 解决问题2.3.1 思路分析2…

计算机网络——SDN

分布式控制路由 集中式控制路由

自动驾驶革命:从特斯拉到百度,谁将主宰未来交通?

内容概要 自动驾驶技术正在经历一个前所未有的革命性变化&#xff0c;各大企业纷纷抢占这一充满潜力的新市场。以特斯拉和百度为代表的行业巨头&#xff0c;正利用各自的优势在这一技术的赛道上展开激烈竞争。特斯拉凭借其在电动汽车和自动驾驶领域的前瞻性设计与不断革新的技…

Group By、Having用法总结(常见踩雷点总结—SQL)

Group By、Having用法总结 目录 Group By、Having用法总结一、 GROUP BY 用法二、 HAVING 用法三、 GROUP BY 和 HAVING 的常见踩雷点3.1 GROUP BY 选择的列必须出现在 SELECT 中&#xff08;&#x1f923;最重要的一点&#xff09;3.2 HAVING 与 WHERE 的区别3.3 GROUP BY 可以…

MySQL存储目录与配置文件(ubunto下)

mysql的配置文件&#xff1a; 在这个目录下&#xff0c;直接cd /etc/mysql/mysql.conf.d mysql的储存目录&#xff1a; /var/lib/mysql Ubuntu版本号&#xff1a;

深度学习经典模型之Network in Network

1 Network in Network 1.1 模型介绍 ​ Network In Network (NIN)是由 M i n L i n Min Lin MinLin等人提出&#xff0c;在CIFAR-10和CIFAR-100分类任务中达到当时的最好水平&#xff0c;因其网络结构是由三个多层感知机堆叠而被成为NIN [ 5 ] ^{[5]} [5]。NIN以一种全新的角…

Java版ERP管理系统源码解析:利用Spring Cloud Alibaba和Spring Boot实现微服务架构

ERP系统&#xff0c;亦称为企业资源计划系统&#xff0c;是一种融合了企业多元部门和复杂业务的综合管理信息系统。在全球经济蓬勃发展及企业竞争日趋激烈的背景下&#xff0c;ERP系统已逐步跃升为现代企业管理的核心工具。该系统通过优化资源配置及提升业务流程效率&#xff0…