Spring Security 核心组件

Spring Security 是一个功能全面的安全框架,用于处理基于 Spring 应用程序的身份验证和授权。

它提供了开箱即用的支持,采用行业标准的做法和机制来保护你的应用。

无论你是开发简单的 Web 应用还是复杂的微服务架构,理解 Spring Security 的核心组件对于实施健壮的安全措施至关重要。

本文将通过示例引导你了解 Spring Security 的核心组件。

Spring Security 核心组件

Spring Security 的架构围绕几个关键组件展开,这些组件协同工作以保护你的应用。我们将探讨这些组件,并提供使用当前最佳实践的示例。

1. 身份验证 (Authentication)

身份验证是验证用户或系统身份的过程,回答“你是谁?”的问题。Spring Security 支持多种身份验证机制,如表单登录、OAuth2 等。

代码示例:

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()).httpBasic(withDefaults()).formLogin(withDefaults());return http.build();}@Beanpublic UserDetailsService userDetailsService() {UserDetails userDetails = User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build();return new InMemoryUserDetailsManager(userDetails);}
}

以上代码是一个典型的 Spring Security 配置示例,用于设置基本的身份验证和授权。以下是对代码的详细解释:

  1. 配置类注解

    • @Configuration:标记该类为配置类。
    • @EnableWebSecurity:启用 Spring Security 的 Web 安全支持。
  2. SecurityFilterChain Bean

    • securityFilterChain 方法定义了安全过滤器链,用于配置 HTTP 安全设置。
    • authorizeHttpRequests:配置请求的授权规则。
      • anyRequest().authenticated():要求所有请求都必须经过身份验证。
    • httpBasic(withDefaults()):启用基本认证(HTTP Basic)。
    • formLogin(withDefaults()):启用表单登录。
  3. UserDetailsService Bean

    • userDetailsService 方法定义了用户详细信息服务。
    • UserDetails:创建一个用户详细信息对象,包含用户名、密码和角色。
    • withDefaultPasswordEncoder:使用默认的密码编码器(不推荐用于生产环境)。
    • InMemoryUserDetailsManager:将用户详细信息存储在内存中。

2. 授权 (Authorization)

身份验证后,授权确定经过身份验证的用户是否有权限执行特定操作或访问资源,回答“你是否可以这样做?”的问题。

代码示例:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorize -> authorize.antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("USER", "ADMIN").antMatchers("/public/**").permitAll().anyRequest().authenticated()).formLogin(withDefaults()).httpBasic(withDefaults());return http.build();
}

以上代码用于设置细粒度的请求授权规则。以下是对代码的详细解释:

代码解释

  1. 配置类注解

    • @Configuration:标记该类为配置类。
    • @EnableWebSecurity:启用 Spring Security 的 Web 安全支持。
  2. SecurityFilterChain Bean

    • filterChain 方法定义了安全过滤器链,用于配置 HTTP 安全设置。
    • authorizeRequests:配置请求的授权规则。
      • antMatchers("/admin/**").hasRole("ADMIN"):匹配 /admin/** 路径的所有请求,要求用户具有 ADMIN 角色。
      • antMatchers("/user/**").hasAnyRole("USER", "ADMIN"):匹配 /user/** 路径的所有请求,要求用户具有 USERADMIN 角色。
      • antMatchers("/public/**").permitAll():匹配 /public/** 路径的所有请求,允许所有用户访问。
      • anyRequest().authenticated():所有其他请求都必须经过身份验证。
    • formLogin(withDefaults()):启用表单登录,默认配置。
    • httpBasic(withDefaults()):启用基本认证(HTTP Basic),默认配置。

3. 主体 (Principal)

主体是指当前经过身份验证的用户详细信息,在整个应用中可用于执行用户特定的操作。

使用示例:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();
// 使用用户名或其他身份验证对象中的详细信息

4. 授予权限 (Granted Authority)

授予权限定义了经过身份验证的用户的权限,指定他们可以执行的操作或访问的资源。

示例:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorize -> authorize.antMatchers("/api/private/**").hasAuthority("ROLE_USER").anyRequest().permitAll()).httpBasic(withDefaults());return http.build();
}

5. 安全上下文和 SecurityContextHolder

Spring Security 的核心是 SecurityContext,它保存当前经过身份验证的用户详细信息,也称为主体。该上下文可以通过 SecurityContextHolder 在整个应用中访问,允许你根据用户的认证状态和权限执行操作。

示例:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {// 根据经过身份验证的用户执行操作
}

6. 用户详细信息 (UserDetails)

UserDetails 接口是 Spring Security 中的核心部分,表示 Spring Security 用于身份验证和授权过程的用户信息。它向框架提供核心用户信息,如:

  • 用户名:用户的唯一标识符。
  • 密码:用户的密码,通常以哈希格式存储。
  • 启用状态:指示用户是否已启用。禁用的用户无法进行身份验证。
  • 账户未过期、凭证未过期、账户未锁定:这些布尔标志提供额外的详细信息,支持复杂的安全部署需求,如账户过期策略和锁定机制。
  • 权限:表示分配给用户的角色或权限的 GrantedAuthority 对象集合,对于授权决策至关重要。

实现 UserDetails 可以让你的应用程序用户实体与 Spring Security 无缝集成。

7. 用户详细信息服务 (UserDetailsService)

UserDetailsService 是 Spring Security 中的一个核心接口,用于从数据源(如数据库、LDAP、内存等)中加载用户特定的数据。这个接口的主要目的是提供一种标准化的方式来获取用户信息,以便 Spring Security 进行身份验证和授权。

它有一个方法 loadUserByUsername(String username),根据用户名查找用户。返回的 UserDetails 对象随后可供 Spring Security 进一步的身份验证和授权过程使用。

实现你自己的 UserDetailsService 涉及创建一个与用户数据库(或其他用户存储机制)交互的服务,以获取用户详细信息并将其转换为 UserDetails 对象。这个自定义服务成为你的用户数据与 Spring Security 需求之间的桥梁。

8. 认证管理器 (AuthenticationManager)

Spring Security 身份验证过程的核心是 AuthenticationManager 接口。它定义了一个方法 authenticate(Authentication authentication),尝试对传递的 Authentication 对象进行身份验证。

AuthenticationManager 负责协调身份验证过程,将请求委托给一个或多个 AuthenticationProvider 实例。

每个 AuthenticationProvider 可以处理特定类型的身份验证(如用户名和密码、基于令牌的身份验证等)。

AuthenticationManager 根据接收到的 Authentication 对象类型,将身份验证请求路由到能够处理它的提供者。

成功的身份验证过程会生成一个包含主体和授予权限的完整 Authentication 对象,该对象随后存储在 SecurityContext 中,以便后续的授权检查。

配置 AuthenticationManager:
在配置类中直接暴露一个 AuthenticationManager bean。以下是一个示例:

@EnableWebSecurity
public class SecurityConfig {@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {return authenticationConfiguration.getAuthenticationManager();}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()).httpBasic(withDefaults()).formLogin(withDefaults());return http.build();}@Beanpublic UserDetailsService userDetailsService() {UserDetails userDetails = User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build();return new InMemoryUserDetailsManager(userDetails);}
}

结论

总之,掌握 Spring Security 的核心组件对于希望保护其 Spring 应用程序的开发者至关重要。从使用 UserDetailsUserDetailsService 进行身份验证,到通过 GrantedAuthority 进行授权,再到使用 SecurityContextHolder 管理安全上下文,每个元素都在安全生态系统中发挥着关键作用。

WebSecurityConfigurerAdapter 到更模块化配置方法的演变,体现了 Spring Security 对灵活性和定制化的承诺。通过理解核心组件并采用新的配置模型,开发者可以实施针对其应用程序特定需求的健壮安全措施。

注:WebSecurityConfigurerAdapter 是 Spring Security 5 之前版本中常用的抽象类,用于简化安全配置。然而,从 Spring Security 5 开始,官方推荐直接使用 SecurityFilterChain Bean 来进行配置,而不是继承 WebSecurityConfigurerAdapter

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

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

相关文章

DataOps for LLM 的数据工程技术架构实践

导读 在 LLM 蓬勃发展的今天,数据工程已成为支持大规模 AI 模型训练的基石。DataOps 作为数据工程的重要方法论,通过优化数据集成、转换和自动化运维,加速数据到模型的闭环流程。本文聚焦新一代数据 & AI 集成工具- Apache SeaTunnel 在…

go-zero(七) RPC服务和ETCD

go-zero 实现 RPC 服务 在实际的开发中,我们是通过RPC来传递数据的,下面我将通过一个简单的示例,说明如何使用go-zero框架和 Protocol Buffers 定义 RPC 服务。 一、生成 RPC项目 在这个教程中,我们根据user.api文件&#xff0…

【c++丨STL】list模拟实现(附源码)

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C、STL 目录 前言 一、节点、迭代器以及函数声明 二、list功能实现 1. 节点 2. 迭代器 迭代器的默认构造 operator* operator-> 前置和-- 后置和--…

SpringBoot:不支持发行版本17超详细解决办法

一开始linux中就已经下好了JDK21,但是后来创建项目的时候选用了JDK23,导致环境错乱,估计大部分都是因为这个原因,接下来我会一步步带大家解决。 检查系统环境(以Ubuntu为例) 没有下载JDK的可以在官网下载…

计算机网络中的数据包传输机制详解

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 计算机网络中的数据包传输机制详解 计算机网络中的数据包传输机制详解 计算机网络中的数据包传输机制详解 引言 数据包的基本概念…

Springboot3.3.5 启动流程之 tomcat启动流程介绍

在文章 Springboot3.3.5 启动流程(源码分析) 中讲到 应用上下文(applicationContext)刷新(refresh)时使用模板方法 onRefresh 创建了 Web Server. 本文将详细介绍 ServletWebServer — Embedded tomcat 的启动流程。 首先&…

HarmonyOs鸿蒙开发实战(9)=>解析json数据,自动生成实体Bean插件-jsonFormat使用教程(铁粉福利)

1.条件:基于HarmonyOs5.0.0版本. 2.老规矩先看效果> 3.第一步 >下载jsonFormat.jar文件,使用版本1.0.5-deveco https://plugins.jetbrains.com/plugin/24930-jsonformat/versions/stable 4.第二步 > 在DevEco Stuio中安装插件 5.第三步 > 新建bean文件&#xff…

VSCode+ESP-IDF开发ESP32-S3-DevKitC-1(2)第一个工程 LED心跳灯

VSCodeESP-IDF开发ESP32-S3-DevKitC-1(2)第一个工程 LED心跳灯 前言1.新建工程2.编写控制LED代码3.LED控制独立成.c和.h文件 前言 实际开发中很多时候我们需要有一个类似心跳灯或运行指示灯的灯以不同的状态闪烁以表示程序的运行状态,所以第…

系统掌握大语言模型提示词 - 从理论到实践

以下是我目前的一些主要个人标签: 6 年多头部大厂软件开发经验;1 年多 AI 业务应用经验,拥有丰富的业务提示词调优经验和模型微调经验。信仰 AGI,已经将 AI 通过自定义 Chatbot /搭建 Agent 融合到我的工作流中。头部大厂技术大学…

FromData格式提交接口时入参被转成JSON格式问题

本地上传文件后通过事件提交文件,一般先通过前端组件生成文本流,在通过接口提交文本流,提交文本流一般使用FormData的入参形式传入,接口请求头也默认"Content-Type": “multipart/form-data”,但是某些场景统…

【插件】重复执行 pytest-repeat

安装 pip3 install pytest-repeat 用法 1.命令行 pytest --count num pytest --count 32.装饰器 pytest.mark.repeat(num) #num运行次数 pytest.mark.repeat(5)#执行结果如下:

【Spring】循环引用 解决流程,只用一二级缓存?

文章目录 循环引用循环引用循环引用解决流程为什么不只用一二级缓存?:red_circle: 循环引用 循环引用 循环依赖:循环依赖其实就是循环引用,也就是bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A 循环依赖在…

【青牛科技】视频监控器应用

1、简介: 我司安防产品广泛应用在视频监控器上,产品具有性能优良,可 靠性高等特点。 2、图示: 实物图如下: 3、具体应用: 标题:视频监控器应用 简介:视频监控器工作原理是光&#x…

机器学习day5-随机森林和线性代数1最小二乘法

十 集成学习方法之随机森林 集成学习的基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类器。大致可以分为:Bagging,Boosting 和 Stacking 三大类型。 (1)每次有放回地从训练集中取出 n 个训练样本&…

5G与4G互通的桥梁:N26接口

5G的商用部署进程将是一个基于4G系统进行的长期的替换、升级、迭代的过程,4G系统是在过渡到5G全覆盖过程中,作为保障用户业务连续性体验这一目的的最好补充。 因此4G/5G融合组网,以及互操作技术将是各大运营商在网络演进中需要重点考虑的问题…

统信UOS开发环境支持Golang

UOS为Golang开发者提供了各种编辑器和工具链的支持,助力开发者实现高质量应用的开发。 文章目录 一、环境部署Golang开发环境安装二、代码示例Golang开发案例三、常见问题1. 包导入错误2. 系统资源限制一、环境部署 Golang开发环境安装 golang开发环境安装步骤如下: 1)安装…

【c++丨STL】list的使用

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C、STL 目录 前言 list简介 一、list的默认成员函数 构造函数(constructor) 析构函数 赋值重载 二、list的迭代器接口 迭代器的功能分类 三、list的容量…

如何解决JAVA程序通过obloader并发导数导致系统夯住的问题 | OceanBase 运维实践

案例背景 某保险机构客户的数据中台,自系统上线后不久,会定期的用 obload 工具从上游业务系统导入数据至OceanBase数据库。但,不久便遇到了应用服务器的 Memory 与 CPU 资源占用持续攀升,最终导致系统夯住而不可用的异常。 memo…

人工智能:塑造未来的工作与生活

目录 人工智能技术的应用前景与影响 人工智能的历史与现状 人工智能的应用领域 人工智能的前景与挑战 个人视角:人工智能的应用前景与未来 人工智能在生活中的潜力 面对人工智能带来的挑战 我的观点与建议 结语 人工智能技术的应用前景与影响 随着人工智能…

MATLAB绘制克莱因瓶

MATLAB绘制克莱因瓶 clc;close all;clear all;warning off;% clear all rand(seed, 100); randn(seed, 100); format long g;% Parameters u_range linspace(0, 2*pi, 100); v_range linspace(0, pi, 50); [U, V] meshgrid(u_range, v_range);% Parametric equations for t…