spring:springboot3使用Spring Security,以及和springboot2的区别

server/2024/10/16 0:08:46/

文章目录

  • springboot3使用Spring Security
    • 介绍
    • 认证与授权
    • 简单示例
    • 核心API
      • UserDetailsService接口
      • PasswordEncoder接口
  • Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别
    • 1. Jakarta EE 迁移
      • 影响:
      • 解决方案:
    • 2. Spring Security 配置方式的变化
      • **Spring Boot 2 配置方式**(基于 `WebSecurityConfigurerAdapter`):
      • Spring Boot 3 配置方式(基于 SecurityFilterChain 和 Lambda DSL):
    • 3. PasswordEncoder 加密方式的变化
    • 4. permitAll() 和 authenticated() 的变化
    • 5. 更强的默认安全设置
    • 6. Java 17 支持与语法提升
    • 7. @PreAuthorize、@Secured 注解的变化
    • 8. 更强的 HTTP/2 和 TLS 支持
    • 9. 更严格的 Bean 注入和依赖管理

springboot3Spring_Security_1">springboot3使用Spring Security

介绍

Spring Security 是一个强大且高度可定制的安全框架,专为保护基于 Java 的应用程序而设计,尤其是 Spring 应用。它提供了一系列功能,帮助开发者实现身份验证(Authentication)、授权(Authorization)、防止常见安全漏洞(如 CSRF 攻击、Session Fixation 等)以及加密等安全措施。

认证与授权

1、用户认证(Authentication):
验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。通俗点说就是系统认为用户是否能登陆。

2、用户授权(Authorization):
验证某个用户是否有权限执行某个操作。在一个系统中,不同用户说具有的权限是不同的。比如对一个文件夹来说,有的用户只能进行读取,有的用户可以进行修改。一般来说,系统不会为不同的用户分配不同的角色,二每个角色则对应一些列的权限。通俗点说就是系统判断用户是否有权限去做某些事情。

简单示例

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

增加 controller

java">package com.security.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@GetMapping("hello")public String add(){return "hello security";}
}

增加 config

java">package com.security.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()  // 所有请求都需要登录).formLogin(form -> form.permitAll()  // 允许所有用户访问默认的登录页面).logout(logout -> logout.permitAll()  // 允许所有用户访问默认的登出页面);return http.build();}
}

浏览器输入 http://localhost:8080/hello 会跳转到 http://localhost:8080/login
在这里插入图片描述
默认账号 user,密码在控制台
在这里插入图片描述
输入账号密码,会回调到 hello 的路由上
在这里插入图片描述

核心API

UserDetailsService接口

当什么也没有配置的时候,帐号和密码是由SPring Security定义生成的,而在实际开发中账户和密码都是从数据库中查询出来,所以要通过自定义逻辑控制认证逻辑。

如果要自定义逻辑时,只需实现UserDetailsService接口即可。接口如下:

java">public interface UserDetailsService {UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

返回值:UserDetails
方法参数:username

如果我们要自己去查数据库,然后认证,需要我们去继承UsernamePasswordAuthenticationFilter,然后实现attemptAuthentication和UsernamePasswordAuthenticationFilter父类的successfulAuthentication和unsuccessfulAuthentication方法,在attemptAuthentication方法中得到用户名和密码,如果认证成功,就会调用successfulAuthentication,不成功就调用unsuccessfulAuthentication。从数据库中获取密码的操作是在UserDetailsService中完成的,这个方法会返回一个User对象,这个对象是由Security提供的。

PasswordEncoder接口

PasswordEncoder 用于对密码进行加密和校验。Spring Security 提供了多种密码加密方式,如 BCryptPasswordEncoder、NoOpPasswordEncoder 等。

主要方法:

  • encode():加密密码。
  • matches():校验明文密码和加密密码是否匹配。
java">PasswordEncoder encoder = new BCryptPasswordEncoder();
String rawPassword = "password";
String encodedPassword = encoder.encode(rawPassword);boolean isMatch = encoder.matches(rawPassword, encodedPassword);  // 验证密码

Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别

Spring Boot 2 升级到 Spring Boot 3,特别是与 Spring Security 的集成和配置,存在一些显著的变化。这些变化主要是由于 Spring Security 5.x 和 6.x 之间的升级,以及 Java 17 的引入和一些基础框架的更新(例如 Jakarta EE 的迁移)。下面我详细说明这两者的主要差异。

1. Jakarta EE 迁移

Spring Boot 3 依赖 Jakarta EE 9,而 Spring Boot 2 使用的是 Java EE(javax 命名空间)。这一变化是 Spring Framework 6 的一部分,导致了 javax.* 命名空间的类迁移到 jakarta.*

  • Spring Boot 2 使用的是 javax.servlet.*javax.validation.* 等类。
  • Spring Boot 3 切换到 jakarta.servlet.*jakarta.validation.*

影响:

如果你的应用程序使用了 javax 命名空间中的类(例如过滤器、Servlets、JPA 等),在 Spring Boot 3 中需要手动迁移到 jakarta 命名空间。

解决方案:

  • 在 Spring Boot 3 中,确保使用 jakarta.* 包替代 javax.*

2. Spring Security 配置方式的变化

Spring Security 在 Spring Boot 3 中更推荐使用新的 DSL 配置,减少对 WebSecurityConfigurerAdapter 的依赖,这个类已经被弃用。

Spring Boot 2 配置方式(基于 WebSecurityConfigurerAdapter):

在 Spring Boot 2 中,通常通过继承 WebSecurityConfigurerAdapter 来配置安全设置。

java">@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}
}

Spring Boot 3 配置方式(基于 SecurityFilterChain 和 Lambda DSL):

在 Spring Boot 3 中,WebSecurityConfigurerAdapter 已被弃用,取而代之的是基于 SecurityFilterChain 和 Lambda 风格的配置。

java">@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.requestMatchers("/public/**").permitAll().anyRequest().authenticated()).formLogin(form -> form.loginPage("/login").permitAll()).logout(logout -> logout.permitAll());return http.build();}
}

主要区别:

  • 弃用了 WebSecurityConfigurerAdapter:Spring Boot 3 推荐使用更简洁的 SecurityFilterChain 和 Lambda 风格配置。
  • 配置更加灵活:通过 Lambda 方式进行配置,增强了代码的可读性。

3. PasswordEncoder 加密方式的变化

Spring Boot 3 仍然使用 PasswordEncoder 来加密和验证密码,但与 Spring Boot 2 相比,密码加密的默认方式和推荐方式发生了细微变化。

Spring Boot 2:
在 Spring Boot 2 中,常见的加密方式是使用 BCryptPasswordEncoder,你可以手动选择或者直接用默认的 NoOpPasswordEncoder(明文)。

java">@Bean
public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
}

Spring Boot 3:
在 Spring Boot 3 中,仍然推荐使用 BCryptPasswordEncoder。不过,Spring Security 6.x 增加了对更强密码策略的关注,并逐渐抛弃了明文密码的方式。·

java">@Bean
public PasswordEncoder passwordEncoder() {return PasswordEncoderFactories.createDelegatingPasswordEncoder();  // 更灵活的密码加密器
}

注意:NoOpPasswordEncoder(不加密的明文存储)不再推荐使用,原因是安全性问题。

4. permitAll() 和 authenticated() 的变化

在 Spring Boot 3 中,HttpSecurity 的 API 有一些调整:

  • authorizeRequests() 被更改为 authorizeHttpRequests(),以更好地反映它的作用范围。
  • anyRequest().authenticated() 等表达方式依然存在,但推荐结合 Lambda 语法使用。

Spring Boot 2 示例:

java">http.authorizeRequests().antMatchers("/public/**").permitAll()  // 允许访问 /public/ 下的资源.anyRequest().authenticated();  // 其他请求都需要认证

Spring Boot 3 示例:

java">http.authorizeHttpRequests(authz -> authz.requestMatchers("/public/**").permitAll()  // 允许访问 /public/ 下的资源.anyRequest().authenticated()  // 其他请求需要认证);

主要变化:从 authorizeRequests() 迁移到 authorizeHttpRequests(),使 API 更加符合 RESTful 风格和表达能力。

5. 更强的默认安全设置

Spring Boot 3 提供了更强的默认安全性配置,默认情况下对 CSRF、CORS、XSS 等安全性问题有更好的保护。

  • CSRF(跨站请求伪造)保护:默认开启,除非显式禁用。
  • HTTP Headers 安全性:Spring Security 6.x 默认增加了一些常见的安全头,比如 Strict-Transport-Security。

在 Spring Boot 2 中,你可能需要手动配置某些安全头或 CSRF 保护。

java">http.csrf().disable();  // 如果你不需要 CSRF,可以禁用

6. Java 17 支持与语法提升

Spring Boot 3 要求 Java 17 作为最低支持版本。对于使用 Java 17 的 Spring Boot 3 应用,你可以利用 Java 17 的新特性,例如 Records、sealed classes 等。

java">record UserDto(String username, String role) {}@Bean
public UserDetailsService userDetailsService() {return username -> {if ("admin".equals(username)) {return User.withUsername("admin").password("{noop}password").roles("ADMIN").build();}throw new UsernameNotFoundException("User not found");};
}

7. @PreAuthorize、@Secured 注解的变化

@PreAuthorize 和 @Secured 注解在 Spring Boot 3 中仍然支持,不过在 Spring Security 6 中这些注解的使用方式保持不变,但是对于 @EnableGlobalMethodSecurity 的配置发生了变化。

Spring Boot 2:

java">@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}

Spring Boot 3:

java">@EnableMethodSecurity  // 更简洁的配置方式
public class MethodSecurityConfig {
}

8. 更强的 HTTP/2 和 TLS 支持

Spring Boot 3 对 HTTP/2 和 TLS 的支持得到了加强,尤其是与安全性相关的配置更加灵活。Spring Security 6 默认包含对更强密码套件的支持,以及对新的 Web 技术(如 WebAuthn)的支持。

9. 更严格的 Bean 注入和依赖管理

Spring Boot 3 强调对依赖的更严格管理,尤其是在安全配置和其他关键组件的配置上,错误的配置将会更早暴露问题。这种变化使得应用程序在编译和启动时会更早发现配置错误,避免在运行时出现潜在的安全风险。


http://www.ppmy.cn/server/132438.html

相关文章

基于Python flask的豆瓣电影可视化系统,豆瓣电影爬虫系统

博主介绍&#xff1a;✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不…

【LeetCode】每日一题 2024_10_15 三角形的最大高度(枚举、模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;三角形的最大高度 代码与解题思路 久违的简单题 这道题读完题目其实不难想到有两条路可以走&#xff1a; 1、题目很明显只有两种情况&#xff0c;枚举是第一个球是红球还是蓝球这两种情…

Java:玩家打怪小游戏

今天&#xff0c;我们尝试用Java来做一个“打怪小游戏”&#xff0c;听名字就知道&#xff0c;我们是应该创建几个成员和怪物&#xff0c;还有知道知道成员和怪物的血量&#xff0c;一次攻击的伤害等等。。当然我们的游戏攻击模式是“回合制”&#xff08;其实是别的方法&#…

云手机哪款好用?2024年云手机推荐对比指南

随着云手机市场的快速扩展&#xff0c;消费者在选择云手机时面临着众多选择。为了帮助大家找到最适合自己的云手机&#xff0c;小编特意整理了一份当前市场上几款备受关注的云手机品牌对比&#xff0c;大家一起往下看吧。 1. Ogphone云手机 Ogphone云手机是近年来海外业务版块迅…

uni-app 打包成app时 限制web-view大小

今天对接一个uni-app的app 内置对方h5 web-view的形式 需要对方在web-view顶部加点东西 对方打的app的web-view始终是全屏的状态&#xff0c;对方表示做不到我要的效果 emmmmmm。。。。。。 于是乎 自己搭了个demo 本地h5跑起来审查了下代码&#xff0c;发现web-view是给绝对定…

mysql集群-主库从库配置--主从库分离

mysql集群 为什么要做主从库分离&#xff1f; 怎么进行分离&#xff1f; 设置2个数据库&#xff0c;为主库从库&#xff0c;主库存储&#xff0c;从库查询 怎么设置&#xff1f; 在你原本的配置yml文件中主库的ip是多少&#xff0c;从库是多少&#xff0c;都要和数据库的ip 一…

PHP DateTime基础用法

PHP DateTime 的用法详解 一、引言 在开发 PHP 应用程序时&#xff0c;处理日期和时间是一个至关重要的任务。PHP 提供了强大的日期和时间处理功能&#xff0c;其中 DateTime 类是最常用的工具之一。DateTime 类提供了丰富的方法来创建、格式化、计算和比较日期时间&#xff…

XGBoost回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出

回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出 目录 回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 XGBoost的全称是eXtreme Gradient Boosting,它是经过优化的分布式梯度提升库,旨在高效、…