🔐 Spring Security + OAuth2 面试10题

2026 Java实习面试 · 安全框架 · 认证授权 · RBAC · JWT · SSO

Q1:Spring Security的核心过滤器链是什么?
SecurityFilterChain 是 Spring Security 的核心。整个流程: UsernamePasswordAuthenticationFilterBasicAuthenticationFilter → ... → FilterSecurityInterceptor
自定义安全配置:继承 SecurityFilterChain Bean,配置 authorizeHttpRequests + oauth2ResourceServer
Q2:JWT和Session认证的区别?什么时候用JWT?
Session:服务端存储状态,基于Cookie。适合单体应用。
JWT:无状态,客户端携带Token,服务端用签名验证。适合分布式/微服务/移动端。
选型:分布式系统用JWT(无需Session共享);对安全性要求极高的内网系统可用Session+Cookie+CSRF防护。
Q3:RBAC权限模型怎么设计?用户-角色-权限表怎么建?
5张核心表:user → user_role(中间) → role → role_permission(中间) → permission。
关键SQL:
SELECT p.code FROM permission p
JOIN role_permission rp ON p.id=rp.permission_id
JOIN user_role ur ON rp.role_id=ur.role_id
WHERE ur.user_id = ?

Spring Security中配合 @PreAuthorize("hasRole('ADMIN')") 注解使用。
Q4:CSRF攻击是什么?Spring Security怎么防御?
CSRF:攻击者诱导用户点击恶意链接,利用用户已登录状态发送伪造请求。
防御:Spring Security默认开启CSRF保护 → 生成 _csrf Token嵌入表单 → 每次POST/PUT/DELETE验证Token。
RESTful API:如果用JWT+无Cookie,天然免疫CSRF,可以 .csrf().disable()
Q5:OAuth2.0四种授权模式?Refresh Token的作用?
四种模式:①授权码模式(Authorization Code) — 最安全,三方登录标准 ②密码模式(Password)— 自家App用 ③客户端模式(Client Credentials)— 服务间调用 ④简化模式(Implicit)— 已废弃。
Refresh Token:Access Token短期(15min),Refresh Token长期(7天)。Access过期后用Refresh换新的,用户无感。
Q6:微服务架构下怎么做认证鉴权?
网关统一鉴权:Gateway Filter 拦截请求 → 验证JWT → 解析userId+roles → 设置Header → 下游服务。
Feign拦截器RequestInterceptor 自动透传JWT,保证服务间调用不丢失认证信息。
白名单:登录接口、Swagger、健康检查不放行会死循环。
Q7:密码怎么安全存储?BCrypt vs MD5?
绝不存明文。MD5+SHA已不安全(彩虹表秒破)。
BCrypt:内置盐值+自适应迭代次数,PasswordEncoder 一行搞定:
matches(rawPassword, encodedPassword) → true/false。
Spring Security默认就是BCrypt,面试说这个就够了。
Q8:分布式Session共享怎么解决?
三种方案:
Redis集中存储(最常用):spring-session-data-redis,所有节点读同一份Session
JWT无状态:不需要Session,Token自包含用户信息
IP Hash粘性:Nginx ip_hash,同一用户始终打到一个节点(不推荐,节点挂了Session丢失)
Q9:@PreAuthorize 和 @Secured 的区别?
@Secured:只支持角色判断,如 @Secured("ROLE_ADMIN")。简单场景够用。
@PreAuthorize:支持SpEL表达式,可以做复杂判断:
@PreAuthorize("hasRole('ADMIN') or #userId == authentication.principal.id")
面试亮点:能说出SpEL+方法级权限控制。
Q10:如何实现单点登录SSO?
OAuth2 + JWT方案:统一认证中心(CAS) → 用户登录一次 → 各子系统通过JWT验证身份。
流程:访问A系统 → 无Token → 跳转认证中心 → 登录 → 拿Token → 访问A/B/C全免登。
关键:Token存Redis,退出时全局失效所有子系统。