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

面试篇: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 SecurityApache 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 {@Overridepublic UserDetails loadUserByUsername(String username) {// 查询数据库返回 UserDetailsreturn 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);
http://www.xdnf.cn/news/5885.html

相关文章:

  • C语言—再学习(数据的存储类别)
  • C++ 字符格式化输出
  • python学习笔记七(文件)
  • 分布式链路跟踪
  • lubuntu 系统详解
  • WebpackVite总结篇与进阶
  • Java SpringMVC 和 MyBatis 整合项目的事务管理配置详解
  • DeepSeek 赋能汽车全生态:从产品到服务的智能化跃迁
  • 2025年5月13日第一轮
  • vue3父子组件传值
  • 数据治理域——日志数据采集设计
  • c++STL-list的模拟实现
  • conda 输出指定python环境的库 输出为 yaml文件
  • K230 ISP:一种新的白平衡标定方法
  • AcroForm 格式化文本(域)字段
  • ElasticSearch父子关系数据建模
  • MySQL命令行导出数据(docker版本)
  • 运行Spark程序-在shell中运行1
  • 智源联合南开大学开源Chinese-LiPS中文多模态语音识别数据集
  • base64形式的图片数据保存方法
  • Redis介绍与使用
  • 【git】clone项目后续,github clone的网络配置,大型项目git log 输出txt,切换commit学习,goland远程,自存档
  • 关于maven的依赖下不下来的问题
  • Git基本操作命令
  • 专题四:综合练习( 找出所有子集的异或总和再求和)
  • 解锁Python TDD:从理论到实战的高效编程之道(9/10)
  • 时间序列预测建模的完整流程以及数据分析【学习记录】
  • 选择单例还是依赖注入
  • 【每天一个知识点】Dip 检验(Dip test)
  • CSS经典布局之圣杯布局和双飞翼布局