Spring Security 认证

news/2024/11/19 22:51:01/

Spring Security 是一个功能强大的安全框架,广泛用于保护 Java 应用程序。它提供了多种认证和授权机制,以确保应用程序的安全性。以下是认证过程的详细概述以及几种常见的认证方式。

认证过程概述

  1. 用户凭证提交

    • 用户通过登录表单提交用户名和密码。通常,这可以通过一个 HTML 表单实现,表单中的 action 属性指向一个处理登录请求的 URL。
  2. 认证令牌创建

    • Spring Security 接收到用户的凭证后,会创建一个 Authentication 对象。这个对象包含了用户的凭证信息(如用户名和密码)以及其他可能的属性。
  3. 认证管理器

    • AuthenticationManager 负责验证 Authentication 对象。它通常会委托给一个或多个 AuthenticationProvider 来执行具体的验证逻辑。每个 AuthenticationProvider 负责特定类型的认证,例如基于数据库的认证或基于 LDAP 的认证。
  4. 安全上下文

    • 如果认证成功,AuthenticationManager 会将 Authentication 对象存储在 SecurityContextHolder 中。SecurityContextHolder 是一个线程局部变量,用于存储当前用户的认证信息,使用户详情在整个请求过程中全局可访问。
  5. 认证结果处理

    • 认证成功后,用户会被重定向到一个成功页面或继续访问受保护的资源。如果认证失败,用户会被重定向到一个错误页面或显示错误消息。

常见认证方式

1. 内存认证

内存认证是最简单的认证方式,适用于测试和开发环境。它将用户详细信息存储在内存中。

java">@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);}
}
2. 数据库认证

数据库认证从自定义数据源(如数据库)加载用户详细信息。你需要实现 UserDetailsService 接口来加载用户信息。

java">@Service
@AllArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {private UserRepository userRepository;@Overridepublic UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail).orElseThrow(() -> new UsernameNotFoundException("User not found by Username or Email: " + usernameOrEmail));Set<GrantedAuthority> authorities = user.getRoles().stream().map((role) -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toSet());return new org.springframework.security.core.userdetails.User(usernameOrEmail,user.getPassword(),authorities);}
}
3. 表单认证

表单认证是最常见的认证方式,用户通过表单提交用户名和密码。Spring Security 提供了默认的表单登录页面和处理逻辑。

java">@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).formLogin(formLogin -> formLogin.loginPage("/login").permitAll().defaultSuccessUrl("/home", true).failureUrl("/login?error=true")).logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true).deleteCookies("JSESSIONID"));return http.build();}
}
4. 基本认证

基本认证是一种简单的 HTTP 认证方案,常用于 API 认证。它通过在 HTTP 请求头中添加 Authorization 头来传递用户名和密码。

java">@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).httpBasic(Customizer.withDefaults());return http.build();}
}
5. JWT 认证

JWT 认证适用于 RESTful API 和微服务,提供了一种无状态的认证方式。JWT 令牌包含用户信息和签名,可以在每次请求时传递。

java">@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {private final JwtTokenProvider jwtTokenProvider;private final UserDetailsService userDetailsService;public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider, UserDetailsService userDetailsService) {this.jwtTokenProvider = jwtTokenProvider;this.userDetailsService = userDetailsService;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {String token = getTokenFromRequest(request);if (StringUtils.hasText(token) && jwtTokenProvider.validateToken(token)) {String username = jwtTokenProvider.getUsername(token);UserDetails userDetails = userDetailsService.loadUserByUsername(username);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authenticationToken);}filterChain.doFilter(request, response);}private String getTokenFromRequest(HttpServletRequest request) {String bearerToken = request.getHeader("Authorization");if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {return bearerToken.substring(7);}return null;}
}
6. OAuth2 认证

OAuth2 是一种授权框架,允许第三方服务代表用户交换资源。Spring Security 提供了对 OAuth2 的全面支持。

java">@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).oauth2Login(oauth2 -> oauth2.loginPage("/login").permitAll().defaultSuccessUrl("/home", true).failureUrl("/login?error=true"));return http.build();}@Beanpublic ClientRegistrationRepository clientRegistrationRepository() {// 配置客户端注册信息return new InMemoryClientRegistrationRepository(this.googleClientRegistration());}private ClientRegistration googleClientRegistration() {return ClientRegistration.withRegistrationId("google").clientId("your-client-id").clientSecret("your-client-secret").clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).redirectUri("{baseUrl}/login/oauth2/code/{registrationId}").scope("openid", "profile", "email").authorizationUri("https://accounts.google.com/o/oauth2/auth").tokenUri("https://accounts.google.com/o/oauth2/token").userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo").userNameAttributeName("sub").jwkSetUri("https://www.googleapis.com/oauth2/v3/certs").clientName("Google").build();}
}

结论

Spring Security 提供了强大的认证机制,支持多种认证方式,包括内存认证、数据库认证、表单认证、基本认证、JWT 认证和 OAuth2 认证。通过理解和应用这些认证机制,你可以确保应用程序的安全性,提供一个安全可靠的数字环境。每种认证方式都有其适用场景,选择合适的认证方式可以更好地满足你的应用需求。


http://www.ppmy.cn/news/1548346.html

相关文章

外包干了2个月,技术明显退步

回望过去&#xff0c;我是一名普通的本科生&#xff0c;于2019年通过校招有幸加入了南京某知名软件公司。那时的我&#xff0c;满怀着对未来的憧憬和热情&#xff0c;投入到了功能测试的岗位中。日复一日&#xff0c;年复一年&#xff0c;转眼间&#xff0c;我已经在这个岗位上…

SpringBoot(二十三)SpringBoot集成JWT

最近整理完docker之后&#xff0c;突然想到&#xff0c;我是不是可以使用docker部署多个blog实例&#xff0c;来实现一下负载均衡呢&#xff1f; 现阶段&#xff0c;blog项目使用的是SESSION来做用户登录信息存储&#xff0c;如果配置负载均衡的话&#xff0c;那session其实就不…

Javaweb-day13事务管理AOP

spring的事务管理&spring框架的第二大核心AOP面向切面编程 spring框架的第一大核心是前面讲的IOC控制反转 事务管理 事务回顾 概念&#xff1a;事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;这些操作要么同时成功&#xff0c;要么同时失败。…

动手学深度学习69 BERT预训练

1. BERT 3亿参数 30亿个词 在输入和loss上有创新 两个句子拼起来放到encoder–句子对 cls-class分类 sep-seperate 分隔符 分开每个句子 告诉是哪个句子 两个句子给不同的向量 位置编码不用sin cos&#xff0c; 让网络自己学习 bert–通用任务 encoder 是双向的&#xff0c;…

前端项目接入单元测试手册

一、单元测试 Vue.js项目中的单元测试是一种软件测试方法&#xff0c;通过对最小的、可测试的代码单元进行检查和验证来保证代码质量。确保每个组件作为独立单元正确执行其预定功能。当代码库随着时间发展增长时&#xff0c;单元测试成为识别错误和避免潜在问题的关键手段。此…

Opengl光照测试

代码 #include "Model.h" #include "shader_m.h" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" //以上是放在同目录的头文件#include <glad/glad.h> #include <GLFW/glfw3.…

Java项目实战II基于Java+Spring Boot+MySQL的共享汽车管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在共享经济…

11.14 机器学习-朴素贝叶斯+决策树算法

# 贝叶斯底层逻辑 一个数据有可能是几种 结果 选一个概率最高的结果赋给它 # 朴素贝叶斯 假设各个特征之间全部独立 P(A*B*C*D*E)P(A)*P(B)*P(C)*P(D)*P(E) # A是特征向量 B是结果 # P(B|A)P(A|B)*P(B)/P(A) # P(A|X1,X2,X3,X4,X5)P(X1,X2,X3,X4,X5|A)*P(A)/P(X1,X2,X3,X4,X5…