Spring Boot OAuth2登录后访问/secured仍被重定向问题求助
你的核心问题是自定义的redirect-uri未被Spring Security OAuth2正确处理,导致授权码交换流程未完成,认证会话未创建,所以访问/secured时系统判定你未登录,触发重定向逻辑。
原因分析
Spring Security OAuth2 Login默认的授权码回调端点是/login/oauth2/code/{registrationId}(对应你的场景就是/login/oauth2/code/github),这个端点由框架自动处理,负责完成授权码与令牌的交换,并创建用户认证会话。
你在配置中将github的redirect-uri设为/redirected,这个端点是你自定义的控制器方法,没有处理OAuth2的授权码交换逻辑,所以Github回调后,系统只是跳转到了该页面,但并未完成用户认证的最终步骤,自然没有生成认证会话。
修复步骤
1. 修正application.yaml中的redirect-uri配置
将redirect-uri改为Spring Security的默认回调地址:
spring: application.name: oauth2-example security: oauth2: client: registration: github: redirect-uri: "{baseUrl}/login/oauth2/code/github" client-id: xxx client-secret: xxx
同时确保Github平台上的重定向URL也更新为http://localhost:8080/login/oauth2/code/github。
2. 调整SecurityConfig(可选,更清晰的配置)
显式允许默认的OAuth2回调端点访问,并指定登录成功后的跳转页面:
@EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .authorizeHttpRequests(authorize -> authorize .requestMatchers("/", "/login", "/redirected", "/error").permitAll() .requestMatchers("/oauth2/authorization/github", "/login/oauth2/code/**").permitAll() .requestMatchers("/secured").authenticated() .anyRequest().authenticated() ) .csrf(AbstractHttpConfigurer::disable) .oauth2Login(oauth2 -> oauth2 .defaultSuccessUrl("/redirected") // 登录成功后跳转到/redirected ) .build(); } }
通过defaultSuccessUrl指定登录成功后的跳转页面,既保留了你想要的跳转逻辑,又让框架完整执行认证流程。
3. 验证认证状态
可以在redirected方法中添加日志,确认用户是否已完成认证:
@GetMapping("/redirected") public String redirected(HttpServletRequest request) { log.info("/redirected: 用户认证状态 -> {}", request.getUserPrincipal() != null); if (request.getUserPrincipal() != null) { log.info("当前用户: {}", request.getUserPrincipal().getName()); } return "redirected"; }
登录成功后如果能打印出用户信息,说明认证会话已创建,此时再访问/secured就不会被重定向。
额外说明
如果因业务需求必须使用自定义redirect-uri,需要手动处理授权码交换:
- 在
/redirected方法中获取请求参数里的code和state - 使用Spring的
OAuth2AuthorizedClientService或WebClient调用Github的令牌接口完成交换 - 手动创建
Authentication对象并存入SecurityContextHolder
但这种方式复杂度较高,新手优先使用框架默认回调流程更稳妥。
内容的提问来源于stack exchange,提问作者cichyvx

