基础概念
什么是Spring Security?
Spring Security 是 Spring 家族中用于提供 认证(Authentication)和授权(Authorization) 的安全框架。它是高度可定制的安全解决方案,支持 Web 安全、方法级安全、OAuth2、JWT 等主流安全机制。
Spring Security 的核心功能有哪些?
-
认证机制:用户名密码验证、基于 Token 的认证(如 JWT)。
-
授权机制:基于角色或权限控制用户访问资源。
-
会话管理:支持登录、登出、会话失效处理等。
-
防止攻击:
-
CSRF(跨站请求伪造)防护
-
XSS(跨站脚本攻击)防护
-
会话固定攻击防护
-
-
方法级安全:使用注解如
@PreAuthorize
控制方法访问。 -
自定义扩展能力强:支持自定义用户服务、认证逻辑、权限模型。
Spring Security 与 Shiro 有何区别?
对比点 | Spring Security | Apache Shiro |
---|---|---|
所属体系 | Spring 全家桶 | 独立安全框架 |
功能丰富度 | 非常丰富,全面支持 OAuth、JWT 等 | 功能较轻量,但易于上手 |
与Spring集成 | 原生集成 | 需手动配置 |
扩展性 | 极强,适合大型项目 | 适中,适合中小型项目 |
认证与授权
Spring Security 的认证流程是怎样的?
认证流程主要包括以下步骤:
-
用户提交用户名和密码。
-
UsernamePasswordAuthenticationFilter
拦截请求,构造Authentication
对象。 -
AuthenticationManager
调用UserDetailsService
获取用户信息。 -
校验密码是否匹配(通过
PasswordEncoder
)。 -
验证成功后,生成
Authentication
对象放入SecurityContextHolder
中。 -
后续请求将携带认证信息,供授权模块判断访问权限。
什么是UserDetails和UserDetailsService?
-
UserDetails
:表示用户的核心信息,如用户名、密码、权限等。 -
UserDetailsService
:用于根据用户名加载用户信息,是认证过程的关键接口。
public class CustomUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) { // 查询数据库返回 UserDetails return new User(...); } }
如何自定义登录认证逻辑?
-
实现
UserDetailsService
加载用户信息。 -
注入
AuthenticationManager
和自定义PasswordEncoder
。 -
可重写
configure(HttpSecurity http)
添加自定义登录 URL、登录成功/失败处理器等。
http.formLogin() .loginPage("/login") .successHandler(mySuccessHandler) .failureHandler(myFailureHandler);
如何实现基于角色或权限的访问控制?
Spring Security 支持三种授权方式:
-
基于 URL 的权限控制:
http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyAuthority("USER_READ");
-
方法级安全控制(需开启
@EnableGlobalMethodSecurity
):
@PreAuthorize("hasRole('ADMIN')") public void deleteUser() { ... }
-
自定义权限决策器:实现
AccessDecisionManager
和PermissionEvaluator
安全配置
Spring Security 默认拦截哪些请求?如何放行静态资源?
默认拦截所有请求(包括静态资源)。可通过 WebSecurityCustomizer
或 HttpSecurity
放行:
@Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/css/**", "/js/**", "/images/**"); }
如何实现自定义的认证入口和异常处理?
使用如下配置实现自定义处理器:
http.exceptionHandling() .authenticationEntryPoint(myEntryPoint) // 未认证处理 .accessDeniedHandler(myAccessDeniedHandler); // 权限不足处理
什么是CSRF?Spring Security如何防护?
-
CSRF(跨站请求伪造) 是一种通过伪装用户请求盗用用户身份的攻击。
-
Spring Security 默认开启 CSRF 防护,需通过
<input type="hidden">
或 header 传递 token。 -
对于 REST API,可关闭 CSRF 防护:
http.csrf().disable();
JWT 与无状态认证
Spring Security 如何集成 JWT?
-
登录成功生成 JWT Token 并返回给前端。
-
前端在请求头中携带 Token。
-
自定义
OncePerRequestFilter
验证 Token 并设置认证信息。 -
配置关闭 session 创建,改为无状态:
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
Spring Security 与 OAuth2 有何关系?
Spring Security 是基础,OAuth2 是其扩展模块。Spring Security 提供 OAuth2 客户端、授权服务器、资源服务器支持。常用于:
-
单点登录(SSO)
-
社交登录(如 GitHub、Google)
-
微服务资源授权
与 Spring Boot 的集成
Spring Boot 中如何使用 Spring Security?
只需引入依赖即可启用默认安全策略:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
-
默认账号:
user
-
默认密码:控制台输出
-
所有请求都需认证
通过继承 WebSecurityConfigurerAdapter
或 SecurityFilterChain
配置自定义规则。
Spring Security 的过滤器链顺序是怎样的?
Spring Security 使用 FilterChainProxy
管理一组安全过滤器,常见顺序如下:
-
SecurityContextPersistenceFilter
-
UsernamePasswordAuthenticationFilter
-
BasicAuthenticationFilter
-
ExceptionTranslationFilter
-
FilterSecurityInterceptor
顺序非常重要,配置错误可能导致认证失败或安全漏洞。
如何在前后端分离项目中使用 Spring Security?
-
前端通过 Ajax 请求登录,后端返回 JWT 或 SessionID。
-
后端提供统一认证入口、异常响应、CORS 支持。
-
设置无状态认证方式,禁用 CSRF、Session。
高级特性
如何实现基于数据库的权限控制模型?
通过数据库定义用户-角色-权限表结构,查询权限信息填充到 GrantedAuthority
,并在 UserDetailsService
中封装返回。
Spring Security 如何实现 Remember Me?
通过配置 rememberMe()
,可在浏览器中持久化登录状态:
http.rememberMe() .tokenValiditySeconds(7 * 24 * 3600) .key("secureKey") .userDetailsService(myUserDetailsService);