0


Spring Security详细介绍及使用含完整代码(值得珍藏)

点击下载《Spring Security详细介绍及使用含完整代码(值得珍藏)》

1. 前言

本文将详细阐述Spring Security的原理、使用方法以及步骤,并通过一个完整的示例来展示如何在Spring Boot项目中集成Spring Security。我们将从Spring Security的基本概念开始,逐步深入到配置和使用,确保读者能够充分理解并掌握Spring Security的核心内容。

2. Spring Security概述

Spring Security是一个功能强大且高度可定制的安全框架,专为基于Spring的企业应用系统提供声明式的安全访问控制解决方案。该框架充分利用了Spring IoC、DI(依赖注入)和AOP(面向切面编程)等核心功能,通过一组可配置的Bean,为应用系统提供声明式的安全访问控制,从而减少了为企业系统安全控制编写大量重复代码的工作量。

Spring Security的核心功能包括用户认证(Authentication)和用户授权(Authorization)。用户认证主要用于验证某个用户是否为系统中的合法主体,即用户能否访问该系统,通常要求用户提供用户名和密码,系统通过校验这些信息来完成认证过程。而用户授权则用于验证某个用户是否有权限执行某个操作,不同用户在系统中可能拥有不同的权限,例如有的用户只能读取文件,而有的用户则能读取和修改文件。系统通常会为不同的用户分配不同的角色,每个角色对应一系列的权限。

此外,Spring Security还提供了多个过滤器,这些过滤器能够拦截进入的请求,并在应用程序处理该请求之前进行某些安全处理,从而增强系统的安全性。用户可以根据自己的需求选择适当的过滤器来保护应用程序。

值得一提的是,在Spring Boot出现之前,整合Spring Security可能较为繁琐,但随着Spring Boot的推出,它为Spring Security提供了自动化配置方案,使得用户可以零配置地使用Spring Security,从而简化了其集成过程。

3. Spring Security原理

Spring Security的原理主要基于过滤器链。当一个请求到达Spring应用时,它首先会经过一系列的过滤器,这些过滤器负责身份验证、授权以及其他安全相关的任务。

Spring Security的过滤器链中包含了多种过滤器,每种过滤器都有其特定的功能。例如:

  • WebAsyncManagerIntegrationFilter用于将Security上下文与Spring Web中用于处理异步请求映射的WebAsyncManager进行集成;
  • SecurityContextPersistenceFilter用于在每次请求处理之前将该请求相关的安全上下文信息加载到SecurityContextHolder中,并在请求处理完成后将这些信息存储到仓储中,如Session,从而维护用户的安全信息;
  • HeaderWriterFilter用于将头信息加入响应中;
  • CsrfFilter用于处理跨站请求伪造;
  • LogoutFilter用于处理退出登录;
  • UsernamePasswordAuthenticationFilter用于处理基于表单的登录请求,从表单中获取用户名和密码进行认证;
  • DefaultLoginPageGeneratingFilter用于在没有配置登录页面时生成一个登录表单页面。
  • BasicAuthenticationFilter用于处理httpBasic登录;
  • ExceptionTranslationFilter用于捕获FilterSecurityInterceptor过滤器抛出的异常等。

在过滤器链的执行过程中,Spring Security会首先检查请求是否是登录请求,并检查登录请求中是否带有用户名和密码。如果有,过滤器会尝试使用这些信息进行登录认证。如果没有,过滤器会将请求回放过给下一个过滤器处理。

4. Spring Security使用

在前后端分离的应用中,Spring Security 依然可以用于保护后端 API。前后端分离通常意味着前端(如使用React, Vue, Angular等构建的单页应用)会发送HTTP请求到后端的RESTful API。这种情况下,Spring Security 的配置会有些不同,因为通常不再需要处理传统的会话管理(如JSP页面)。

下面是一个Spring Security在前后端分离应用中的基本配置示例,使用OAuth2的JWT(JSON Web Tokens)作为认证机制。

4.1 依赖配置

首先,添加必要的依赖到你的

pom.xml

文件中:

<dependencies><!-- Spring Security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- JWT --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- Other dependencies... --></dependencies>

4.2 Security配置

然后,创建一个配置类来设置Spring Security:

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.authentication.AuthenticationManager;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.core.userdetails.User;importorg.springframework.security.core.userdetails.UserDetailsService;importorg.springframework.security.crypto.password.PasswordEncoder;importorg.springframework.security.oauth2.jwt.Jwt;importorg.springframework.security.oauth2.jwt.JwtDecoder;importorg.springframework.security.oauth2.jwt.NioJwtDecoder;importjava.util.Collections;@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{// 模拟用户服务,实际开发中应该使用数据库或其他持久化存储  @Bean@OverridepublicUserDetailsServiceuserDetailsService(){// 创建内存中的用户,实际开发中应从数据库或其他存储中获取  User user =User.withUsername("user").password(passwordEncoder().encode("password")).roles("USER").build();returnnewInMemoryUserDetailsManager(Collections.singletonList(user));}@BeanpublicPasswordEncoderpasswordEncoder(){// 使用BCrypt进行密码编码  returnnewBCryptPasswordEncoder();}@Bean@OverrideprotectedAuthenticationManagerauthenticationManager()throwsException{returnsuper.authenticationManager();}@BeanpublicJwtDecoderjwtDecoder(){// 这里使用固定的密钥,实际开发中应该使用安全的密钥管理方式  String secret ="mySecret";returnJwtDecoders.fromSecretKey(secret);}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{  
        http  
            .csrf().disable().authorizeRequests().antMatchers("/login").permitAll()// 允许所有用户访问登录端点  .anyRequest().authenticated()// 其他所有请求需要认证  .and().addFilterBefore(newJwtAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);}}

4.3 用户服务

在实际应用中,你可能需要一个用户服务来从数据库中获取用户信息。这里我们创建一个简单的

UserService

类,但在本示例中不会使用它,因为我们在配置中使用了内存中的用户。

importorg.springframework.security.core.userdetails.User;importorg.springframework.security.core.userdetails.UserDetails;importorg.springframework.security.core.userdetails.UserDetailsService;importorg.springframework.security.core.userdetails.UsernameNotFoundException;importorg.springframework.stereotype.Service;@ServicepublicclassUserServiceimplementsUserDetailsService{@OverridepublicUserDetailsloadUserByUsername(String username)throwsUsernameNotFoundException{// 在实际应用中,这里应该根据用户名从数据库或其他数据源加载用户  // 假设我们有一个用户名为"user",密码为"password"的用户  if("user".equals(username)){returnnewUser("user","$2a$10$dXJ3SW6G7P50lGmMkkmwe.20c02F55t218l9.kR6l/.6",newArrayList<>());}else{thrownewUsernameNotFoundException("User not found with username: "+ username);}}}

4.4 创建JWT认证过滤器

这个过滤器会检查HTTP请求头中的Authorization字段,验证JWT令牌,并在验证成功后将用户信息放入Spring Security的上下文中。

importorg.springframework.security.authentication.UsernamePasswordAuthenticationToken;importorg.springframework.security.core.Authentication;importorg.springframework.security.core.context.SecurityContextHolder;importorg.springframework.security.core.userdetails.UserDetails;importorg.springframework.security.oauth2.jwt.Jwt;importorg.springframework.security.oauth2.jwt.JwtDecoder;importorg.springframework.security.web.authentication.WebAuthenticationDetailsSource;importorg.springframework.stereotype.Component;importorg.springframework.web.filter.OncePerRequestFilter;importjavax.servlet.FilterChain;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;@ComponentpublicclassJwtAuthenticationFilterextendsOncePerRequestFilter{privatefinalJwtDecoder jwtDecoder;publicJwtAuthenticationFilter(JwtDecoder jwtDecoder){this.jwtDecoder = jwtDecoder;}@OverrideprotectedvoiddoFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain)throwsServletException,IOException{finalString authorizationHeader = request.getHeader("Authorization");String username =null;String jwt =null;if(authorizationHeader !=null&& authorizationHeader.startsWith("Bearer ")){  
            jwt = authorizationHeader.substring(7);try{Jwt jwtParsed = jwtDecoder.decode(jwt);  
                username = jwtParsed.getSubject();}catch(Exception e){// 无效的JWT令牌  
                logger.warn("Invalid JWT token");}}if(username !=null&&SecurityContextHolder.getContext().getAuthentication()==null){UserDetails userDetails =this.userDetailsService.loadUserByUsername(username);if(jwt !=null){UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =newUsernamePasswordAuthenticationToken(userDetails,null, userDetails.getAuthorities());  
                usernamePasswordAuthenticationToken  
                        .setDetails(newWebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);}}  
  
        filterChain.doFilter(request, response);}}

请注意,这个过滤器依赖于

JwtDecoder

UserDetailsService

JwtDecoder

用于解码JWT令牌,而

UserDetailsService

用于加载用户详细信息。在实际应用中,您可能需要将这些依赖项通过构造函数注入到过滤器中,就像上面的代码示例所做的那样。

此外,这个过滤器检查HTTP请求头中的

Authorization

字段,并期望它以

Bearer <token>

的形式出现。如果令牌有效,过滤器会创建一个

UsernamePasswordAuthenticationToken

并将其设置为Spring Security的上下文中的认证信息。如果令牌无效或不存在,过滤器不会进行任何操作,并允许请求继续通过过滤器链。

5. 总结

通过以上详细的讲解和示例,我们深入了解了Spring Security的原理、使用方法以及步骤。Spring Security作为Spring生态中不可或缺的安全框架,提供了全面的安全解决方案,帮助开发者简化安全配置,确保应用的安全性。在实际项目中,我们可以根据具体需求进行配置,以满足不同的安全要求。通过本文的学习,相信读者已经掌握了Spring Security的核心内容,并能够在实际项目中灵活运用。

点击下载《Spring Security详细介绍及使用含完整代码(值得珍藏)》


本文转载自: https://blog.csdn.net/a342874650/article/details/136077550
版权归原作者 孤蓬&听雨 所有, 如有侵权,请联系我们删除。

“Spring Security详细介绍及使用含完整代码(值得珍藏)”的评论:

还没有评论