当前位置: 首页 > news >正文

Spring Security 框架

目录

一、什么是 Spring Security?

✅ 核心功能:

二、Spring Security 核心概念

1. Authentication(认证)

2. UserDetails & UserDetailsService

3. PasswordEncoder

4. GrantedAuthority

5. SecurityContext & SecurityContextHolder

三、Spring Security 工作流程(认证过程)

四、常用配置方式(Spring Boot)

1. 引入依赖(Maven)

2. 基础配置类(启用 Web 安全)

3. 自定义 UserDetailsService

五、权限控制(授权 Authorization)

1. 方法级别权限(推荐)

2. 页面级别权限(Thymeleaf)

六、常见自定义扩展

1. 自定义登录成功/失败处理器

2. 自定义权限异常处理

七、与 JWT / 前后端分离集成(简要)

八、最佳实践 & 注意事项

✅ 总结一句话:

📚 学习路径建议:

💡 送你一个完整可运行的最小示例结构:


一、什么是 Spring Security?

Spring Security 是一个功能强大、高度可定制的身份验证(Authentication)和访问控制(Authorization)框架,是保护基于 Spring 的应用的事实标准。

✅ 核心功能:

  • 用户登录认证(Authentication)
  • 权限控制、角色控制(Authorization)
  • 防止 CSRF、会话固定、点击劫持等攻击
  • 支持多种登录方式:表单登录、HTTP Basic、OAuth2、JWT、LDAP 等
  • 与 Spring Boot 无缝集成

二、Spring Security 核心概念

1. Authentication(认证)

  • 代表“当前用户是谁”,包含用户名、密码、权限等。
  • 由 AuthenticationManager 管理认证过程。

2. UserDetails & UserDetailsService

  • UserDetails:封装用户信息(用户名、密码、权限、是否锁定等)
  • UserDetailsService:根据用户名加载 UserDetails
@Override
public UserDetails loadUserByUsername(String username) {// 从数据库查用户 → 返回 UserDetails(含加密密码 + 权限)
}

3. PasswordEncoder

  • 用于加密密码和比对密码。
  • 永远不要存储明文密码!
  • 常用实现:BCryptPasswordEncoderSCryptPasswordEncoderPbkdf2PasswordEncoder
// 注册时:
user.setPassword(passwordEncoder.encode(rawPassword));// 登录时(框架自动调用):
passwordEncoder.matches(rawPassword, encodedPassword); // true/false

4. GrantedAuthority

  • 代表一个权限,如 "ROLE_ADMIN""user:delete"
  • 通常以 ROLE_ 开头表示角色,其它表示具体权限。

5. SecurityContext & SecurityContextHolder

  • 存储当前登录用户的信息(Authentication 对象)。
  • 可在任何地方获取当前用户:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();

三、Spring Security 工作流程(认证过程)

sequenceDiagramparticipant Userparticipant Filter as FilterChain (Spring Security)participant Provider as AuthenticationProviderparticipant Service as UserDetailsServiceparticipant Encoder as PasswordEncoderUser->>Filter: 提交用户名/密码Filter->>Provider: 调用 authenticate()Provider->>Service: loadUserByUsername(username)Service-->>Provider: 返回 UserDetails(含加密密码)Provider->>Encoder: matches(输入密码, 数据库加密密码)alt 匹配成功Encoder-->>Provider: trueProvider-->>Filter: 返回认证成功 AuthenticationFilter->>User: 登录成功,跳转else 匹配失败Encoder-->>Provider: falseProvider-->>Filter: 抛出异常Filter->>User: 登录失败end

四、常用配置方式(Spring Boot)

1. 引入依赖(Maven)

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

2. 基础配置类(启用 Web 安全)

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.requestMatchers("/login", "/register", "/css/**").permitAll().requestMatchers("/admin/**").hasRole("ADMIN").requestMatchers("/user/**").hasAnyRole("USER", "ADMIN").anyRequest().authenticated()).formLogin(form -> form.loginPage("/login")           // 自定义登录页.defaultSuccessUrl("/home")    // 登录成功跳转.permitAll()).logout(logout -> logout.logoutSuccessUrl("/login?logout").permitAll());return http.build();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(); // 推荐使用 BCrypt}
}

3. 自定义 UserDetailsService

@Component
public class MyUserServiceImpl implements UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userMapper.findUserByName(username);if (user == null) throw new UsernameNotFoundException("用户不存在");// ✅ 直接返回数据库中的加密密码(注册时已加密存储!)return User.builder().username(user.getUsername()).password(user.getSupwd()) // ← 不要再 encode!.roles("USER") // 或者 .authorities(getAuthorities()).build();}
}

五、权限控制(授权 Authorization)

1. 方法级别权限(推荐)

@Service
public class ArticleService {@PreAuthorize("hasRole('ADMIN')") // 需要 ADMIN 角色public void deleteArticle(Long id) {// ...}@PreAuthorize("hasAuthority('article:edit')") // 需要具体权限public void editArticle(Article article) {// ...}@PostAuthorize("returnObject.owner == authentication.name")public Article getArticle(Long id) {// 返回后检查:只有文章主人才能看}
}

⚠️ 要启用方法级权限,需在配置类加:@EnableMethodSecurity

@Configuration
@EnableWebSecurity
@EnableMethodSecurity // ← 启用 @PreAuthorize 等注解
public class SecurityConfig { ... }

2. 页面级别权限(Thymeleaf)

<!-- 只有 ADMIN 能看到 -->
<div sec:authorize="hasRole('ADMIN')"><a href="/admin">管理后台</a>
</div><!-- 显示当前用户名 -->
<span sec:authentication="name"></span>

需引入:

<dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>

六、常见自定义扩展

1. 自定义登录成功/失败处理器

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {response.sendRedirect("/home?loginSuccess");}
}

在配置中使用:

.formLogin(form -> form.successHandler(mySuccessHandler).failureHandler(myFailureHandler)
)

2. 自定义权限异常处理

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {response.sendRedirect("/403");}
}

配置:

.exceptionHandling(ex -> ex.accessDeniedHandler(myAccessDeniedHandler)
)

七、与 JWT / 前后端分离集成(简要)

如果你是前后端分离项目(如 Vue + Spring Boot),通常不用 Session,改用 JWT:

  1. 用户 POST /login 提交用户名密码
  2. 后端验证成功 → 生成 JWT Token 返回
  3. 前端后续请求在 Header 中携带 Authorization: Bearer <token>
  4. 后端用 Filter 解析 Token → 设置 SecurityContext

⚠️ 此时 UserDetailsService 依然有用 —— 用于从 Token 中的用户名加载用户权限!


八、最佳实践 & 注意事项

项目建议
密码存储必须加密(BCrypt 最常用)
密码比对交给 Spring Security,不要手动比对
权限设计角色(ROLE_) + 细粒度权限(user:delete)结合
登录页可自定义,但路径要 permitAll
CSRF表单登录默认开启,JWT 项目可关闭
调试可临时 .authorizeHttpRequests(authz -> authz.anyRequest().permitAll()) 放行所有

✅ 总结一句话:

Spring Security = 认证(你是谁)+ 授权(你能干什么)+ 安全防护,你只需要提供“用户数据”和“权限规则”,框架自动完成验证和拦截。


📚 学习路径建议:

  1. 先跑通表单登录 + 自定义 UserDetailsService
  2. 学会配置 URL 权限控制
  3. 掌握方法级权限 @PreAuthorize
  4. 学习自定义处理器(登录成功/失败、无权限)
  5. 进阶:JWT、OAuth2、方法权限表达式、动态权限

💡 送你一个完整可运行的最小示例结构:

src/
├── controller/
│   └── LoginController.java       // 登录页、首页
├── service/
│   └── MyUserServiceImpl.java     // loadUserByUsername
├── config/
│   └── SecurityConfig.java        // 权限配置 + PasswordEncoder
└── entity/└── User.java                  // 用户实体(含加密密码字段)

http://www.dtcms.com/a/388795.html

相关文章:

  • Qt QPercentBarSeries详解
  • RTT操作系统(3)
  • DNS服务管理
  • IDA Pro配置与笔记
  • 虚函数表在单继承与多继承中的实现机制
  • 矿石生成(1)
  • Linux 线程的概念
  • Unity学习之资源管理(Resources、AssetDatabase、AssetBundle、Addressable)
  • LG P5138 fibonacci Solution
  • 删除UCPD监控服务或者监控驱动
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(33):文法運用第10回1+(考え方14)
  • 向量技术研究报告:从数学基础到AI革命的支柱
  • 802.1x和802.1Q之间关联和作用
  • 基于大模型多模态的人体体型评估:从“尺码测量”到“视觉-感受”范式
  • 更符合人类偏好的具身导航!HALO:面向机器人导航的人类偏好对齐离线奖励学习
  • Transformer多头注意力机制
  • git 分支 error: src refspec sit does not match any`
  • VN1640 CH5 I/O通道终极指南:【VN1630 I/O功能在电源电压时间精确度测试中的深度应用】
  • qt QHorizontalBarSeries详解
  • 半导体制造的芯片可靠性测试的全类别
  • MySQL 索引详解:原理、类型与优化实践
  • AI 重塑就业市场:哪些岗位将被替代?又会催生哪些新职业赛道?
  • mysql表分区备份太慢?如何精准“狙击”所需数据?
  • InVEST实践及在生态系统服务供需、固碳、城市热岛、论文写作等实际项目中应用
  • 数据库视图详解
  • C#并行处理CPU/内存监控:用PerformanceCounter实时监控,避免资源过载(附工具类)
  • 数据结构初阶——红黑树的实现(C++)
  • PS练习1:将风景图放到相框中
  • Seedream 4.0深度评测:新一代AI图像创作的革命性突破
  • Python中的异常和断言