面试篇:Spring Security

基础概念

什么是Spring Security?

Spring Security 是 Spring 家族中用于提供 认证(Authentication)和授权(Authorization) 的安全框架。它是高度可定制的安全解决方案,支持 Web 安全、方法级安全、OAuth2、JWT 等主流安全机制。


Spring Security 的核心功能有哪些?

  1. 认证机制:用户名密码验证、基于 Token 的认证(如 JWT)。

  2. 授权机制:基于角色或权限控制用户访问资源。

  3. 会话管理:支持登录、登出、会话失效处理等。

  4. 防止攻击

    • CSRF(跨站请求伪造)防护

    • XSS(跨站脚本攻击)防护

    • 会话固定攻击防护

  5. 方法级安全 :使用注解如 @PreAuthorize 控制方法访问。

  6. 自定义扩展能力强:支持自定义用户服务、认证逻辑、权限模型。


Spring Security 与 Shiro 有何区别?

对比点 Spring Security Apache Shiro
所属体系 Spring 全家桶 独立安全框架
功能丰富度 非常丰富,全面支持 OAuth、JWT 等 功能较轻量,但易于上手
与Spring集成 原生集成 需手动配置
扩展性 极强,适合大型项目 适中,适合中小型项目

认证与授权

Spring Security 的认证流程是怎样的?

认证流程主要包括以下步骤:

  1. 用户提交用户名和密码。

  2. UsernamePasswordAuthenticationFilter 拦截请求,构造 Authentication 对象。

  3. AuthenticationManager 调用 UserDetailsService 获取用户信息。

  4. 校验密码是否匹配(通过 PasswordEncoder)。

  5. 验证成功后,生成 Authentication 对象放入 SecurityContextHolder 中。

  6. 后续请求将携带认证信息,供授权模块判断访问权限。


什么是UserDetails和UserDetailsService?

  • UserDetails:表示用户的核心信息,如用户名、密码、权限等。

  • UserDetailsService:用于根据用户名加载用户信息,是认证过程的关键接口。

复制代码
public class CustomUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) {
        // 查询数据库返回 UserDetails
        return new User(...);
    }
}

如何自定义登录认证逻辑?

  1. 实现 UserDetailsService 加载用户信息。

  2. 注入 AuthenticationManager 和自定义 PasswordEncoder

  3. 可重写 configure(HttpSecurity http) 添加自定义登录 URL、登录成功/失败处理器等。

复制代码
http.formLogin()
    .loginPage("/login")
    .successHandler(mySuccessHandler)
    .failureHandler(myFailureHandler);

如何实现基于角色或权限的访问控制?

Spring Security 支持三种授权方式:

  1. 基于 URL 的权限控制
复制代码
http.authorizeRequests()
    .antMatchers("/admin/**").hasRole("ADMIN")
    .antMatchers("/user/**").hasAnyAuthority("USER_READ");
  1. 方法级安全控制 (需开启 @EnableGlobalMethodSecurity):
复制代码
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser() { ... }
  1. 自定义权限决策器 :实现 AccessDecisionManagerPermissionEvaluator

安全配置

Spring Security 默认拦截哪些请求?如何放行静态资源?

默认拦截所有请求(包括静态资源)。可通过 WebSecurityCustomizerHttpSecurity 放行:

复制代码
@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?

  1. 登录成功生成 JWT Token 并返回给前端。

  2. 前端在请求头中携带 Token。

  3. 自定义 OncePerRequestFilter 验证 Token 并设置认证信息。

  4. 配置关闭 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

  • 默认密码:控制台输出

  • 所有请求都需认证

通过继承 WebSecurityConfigurerAdapterSecurityFilterChain 配置自定义规则。


Spring Security 的过滤器链顺序是怎样的?

Spring Security 使用 FilterChainProxy 管理一组安全过滤器,常见顺序如下:

  1. SecurityContextPersistenceFilter

  2. UsernamePasswordAuthenticationFilter

  3. BasicAuthenticationFilter

  4. ExceptionTranslationFilter

  5. FilterSecurityInterceptor

顺序非常重要,配置错误可能导致认证失败或安全漏洞。


如何在前后端分离项目中使用 Spring Security?

  1. 前端通过 Ajax 请求登录,后端返回 JWT 或 SessionID。

  2. 后端提供统一认证入口、异常响应、CORS 支持。

  3. 设置无状态认证方式,禁用 CSRF、Session。


高级特性

如何实现基于数据库的权限控制模型?

通过数据库定义用户-角色-权限表结构,查询权限信息填充到 GrantedAuthority,并在 UserDetailsService 中封装返回。


Spring Security 如何实现 Remember Me?

通过配置 rememberMe(),可在浏览器中持久化登录状态:

复制代码
http.rememberMe()
    .tokenValiditySeconds(7 * 24 * 3600)
    .key("secureKey")
    .userDetailsService(myUserDetailsService);
相关推荐
欧先生^_^3 小时前
Linux内核可配置的参数
linux·服务器·数据库
问道飞鱼3 小时前
【数据库知识】Mysql进阶-高可用MHA(Master High Availability)方案
数据库·mysql·adb·高可用·mha
tiging3 小时前
centos7.x下,使用宝塔进行主从复制的原理和实践
数据库·mysql·adb·主从复制
海尔辛4 小时前
学习黑客5 分钟读懂Linux Permissions 101
linux·学习·安全
wangcheng86994 小时前
Oracle常用函数-日期时间类型
数据库·sql·oracle
玉笥寻珍4 小时前
Web安全渗透测试基础知识之HTTP参数污染篇
网络·网络协议·安全·web安全·http
一只fish4 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(2)
数据库·mysql
StarRocks_labs4 小时前
从InfluxDB到StarRocks:Grab实现Spark监控平台10倍性能提升
大数据·数据库·starrocks·分布式·spark·iris·物化视图
搞不懂语言的程序员5 小时前
Redis的Pipeline和Lua脚本适用场景是什么?使用时需要注意什么?
数据库·redis·lua