React+Spring Boot全栈项目如何对接组织SSO实现统一鉴权
Spring Security默认账号密码认证问题修复
你遇到的默认触发账号密码提示的问题,是因为引入Spring Security依赖后,框架默认加载UsernamePasswordAuthenticationFilter,未认证请求会自动走表单登录/HTTP Basic认证流程,和SSO认证逻辑不兼容,按以下方式调整即可:
- 在Security配置类中显式关闭默认的表单登录、HTTP Basic认证能力,将默认的未认证跳转逻辑替换为直接返回401状态码,避免弹出账号密码输入框或跳转到框架自带的登录页
- 新增自定义认证过滤器(继承
OncePerRequestFilter即可),放在过滤器链中UsernamePasswordAuthenticationFilter之前执行,专门解析请求中携带的SSO认证凭据(JWT或SSO票据),校验通过后构造已认证的Authentication对象存入SecurityContext,后续过滤器链会直接识别为已认证请求,不会再触发默认的账号密码校验
核心配置示例:
@Configuration @EnableWebSecurity public class SsoSecurityConfig { @Bean public SecurityFilterChain defaultSecurityChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) // 关闭默认认证方式 .formLogin(form -> form.disable()) .httpBasic(basic -> basic.disable()) // 未认证请求直接返回401,不做登录跳转 .exceptionHandling(e -> e.authenticationEntryPoint((req, resp, ex) -> { resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); resp.setContentType("application/json;charset=utf-8"); resp.getWriter().write("{\"code\":401,\"msg\":\"未登录或登录已过期\"}"); })) .authorizeHttpRequests(auth -> auth .requestMatchers("/public/**", "/sso/callback/**").permitAll() .anyRequest().authenticated() ) // 注入自定义SSO凭据校验过滤器 .addFilterBefore(ssoTokenValidateFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } }
Spring Boot最优SSO接入方案与前后端路由跳转逻辑
不要自己从零实现SSO协议逻辑,优先用Spring Security官方封装的认证组件,目前企业级SSO基本都基于OAuth2/OIDC授权码模式或SAML2协议,这两类协议Spring Security都提供了开箱即用的支持,比自己手写JWT校验逻辑稳定性、安全性高很多。
根据SSO对接要求的不同,分两种常用流程:
- 后端作为OAuth2/SAML2客户端(最推荐,适配绝大多数内部组织SSO场景):
所有SSO对接逻辑放在后端实现,前端不需要感知SSO协议细节,跳转流程如下:- React前端加全局路由守卫,判断本地是否存在有效登录凭据,没有的话直接跳后端提供的SSO发起端点
- 后端端点自动重定向到组织SSO登录页,用户完成SSO侧认证后,SSO会携带授权码/断言回调到后端预留的回调地址
- 后端通过回调参数向SSO服务端换取完整用户信息,校验通过后给前端签发自有认证凭据(可以是短有效期JWT,也可以是Session凭据),再重定向回前端业务页面,通过Set-Cookie或URL参数把凭据传给前端
- 前端拿到凭据后妥善存储,后续接口请求自动携带凭据即可
- 前端必须直接对接SSO(比如组织强制要求使用前端SSO SDK):
后端直接配置为OAuth2资源服务器,不需要写自定义校验过滤器,只需要配置SSO服务的JWT验签规则,前端从SSO拿到令牌后,后续请求把令牌放在Authorization请求头传给后端,后端自动完成令牌校验、权限解析,不需要额外开发对接逻辑。
React+Spring Boot栈SSO鉴权最佳实践
- 权责划分清晰:前端只做路由层面的访问拦截、未登录/无权限的友好提示,所有接口的权限校验逻辑必须全部放在后端Spring Security实现,前端的校验仅用于优化用户体验,不能作为安全防护手段
- 凭据存储适配部署场景:如果前端IIS和后端Tomcat部署在同一一级域名下,优先用带HttpOnly、Secure、SameSite属性的Cookie存储认证凭据,前端不需要手动处理凭据存取,XSS风险远低于localStorage存储方案;如果是跨域部署,把短有效期JWT存在前端内存中,刷新令牌存在HttpOnly Cookie中,降低令牌泄露风险
- 统一异常交互:后端对认证失败、权限不足的请求统一返回固定结构的JSON响应,不要返回框架默认的HTML登录页或错误页;React前端配置全局响应拦截器,统一处理401(跳转登录/重新拉取令牌)、403(跳转无权限提示页)逻辑,不需要每个接口单独处理
- 登出逻辑闭环:登出时不仅要清除前端存储的所有认证凭据、跳转SSO全局登出接口,后端也要同步清除当前用户的SecurityContext,使用JWT方案时要控制令牌有效期在15-30分钟,搭配刷新令牌续期,避免令牌泄露后被长期冒用
- 不要自研SSO协议逻辑:不管是OAuth2流程的授权码交换、令牌验签,还是SAML2的断言解析,全部用Spring Security官方提供的成熟组件,不要自己手写协议逻辑,避免出现校验绕过、签名伪造这类安全漏洞
- 提前配置跨域规则:如果前后端不同源,在Spring Security配置中提前注入Cors过滤器,允许前端域名跨域访问,配置允许携带认证凭据(Cookie/Authorization头),避免联调阶段出现跨域拦截问题
内容的提问来源于stack exchange,提问作者Ramakrishna
相关产品推荐
相关产品推荐

