You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security OAuth2授权登录后404,无法重定向至前端

解决Spring Security OAuth2表单登录后404及前端重定向问题

针对表单登录后无法重定向到http://localhost:5173/出现404的问题,结合后续社交登录的需求,以下是具体的修复和配置方案:

一、修正授权服务器的重定向URI白名单

首先要确保前端地址被加入授权服务器允许的重定向列表,授权码模式要求redirect_uri必须精确匹配(或配置通配符规则)。修改RegisteredClient配置:

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient frontendClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("frontend-client")
            .clientSecret("{noop}frontend-secret") // 生产环境替换为加密密码
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            // 添加前端回调地址,支持授权码回调和首页跳转
            .redirectUri("http://localhost:5173/login/oauth2/code/frontend-client")
            .redirectUri("http://localhost:5173/")
            .scope(OidcScopes.OPENID)
            .scope("read")
            .scope("write")
            .clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())
            .build();

    return new InMemoryRegisteredClientRepository(frontendClient);
}

二、调整表单登录后的跳转逻辑

表单登录成功后,需要引导用户完成OAuth2授权流程,而不是直接跳转前端。自定义AuthenticationSuccessHandler实现自动跳转授权端点:

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
    http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults()); // 启用OIDC,为社交登录铺路

    http
            .formLogin(form -> form
                    .successHandler((request, response, auth) -> {
                        // 从请求参数中获取授权所需的参数,跳转至授权端点
                        String redirectUri = request.getParameter("redirect_uri");
                        String clientId = request.getParameter("client_id");
                        String scope = request.getParameter("scope");
                        String state = request.getParameter("state");

                        String authUrl = String.format(
                                "/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s",
                                clientId, URLEncoder.encode(redirectUri, StandardCharsets.UTF_8), scope, state
                        );
                        response.sendRedirect(authUrl);
                    })
            )
            .exceptionHandling(exceptions -> exceptions
                    .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
            );

    return http.build();
}

三、配置资源服务器跨域支持

前端和后端属于跨域场景,必须在资源服务器中配置CORS:

@Bean
public CorsFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(List.of("http://localhost:5173"));
    config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    config.setAllowedHeaders(List.of("*"));
    config.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

// 资源服务器Security配置中启用CORS
@Bean
public SecurityFilterChain resourceServerSecurityFilterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .cors(Customizer.withDefaults());

    return http.build();
}

四、前端处理授权回调获取Token

前端需要在指定路径接收授权码,然后请求Token并保存。以Vue3为例:

路由配置

{
  path: '/login/oauth2/code/frontend-client',
  component: () => import('../views/OAuth2Callback.vue')
}

回调页面逻辑

<script setup>
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';

const route = useRoute();
const router = useRouter();

const code = route.query.code;
if (code) {
  axios.post('http://localhost:8080/oauth2/token', new URLSearchParams({
    client_id: 'frontend-client',
    client_secret: 'frontend-secret',
    grant_type: 'authorization_code',
    code: code,
    redirect_uri: 'http://localhost:5173/login/oauth2/code/frontend-client'
  }), {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
  }).then(res => {
    localStorage.setItem('access_token', res.data.access_token);
    localStorage.setItem('refresh_token', res.data.refresh_token);
    router.push('/'); // 跳转到首页
  }).catch(err => {
    console.error('Token获取失败:', err);
    router.push('/login');
  });
}
</script>

五、社交登录前置配置

如果后续要接入社交登录(如GitHub、Google),提前在授权服务器中启用OAuth2登录,并配置客户端信息:

// 在授权服务器SecurityFilterChain中添加
http
        .oauth2Login(oauth2 -> oauth2
                .successHandler((request, response, auth) -> {
                    // 社交登录成功后同样引导至授权端点,复用授权流程
                    String redirectUri = request.getParameter("redirect_uri");
                    String clientId = request.getParameter("client_id");
                    String scope = request.getParameter("scope");
                    String state = request.getParameter("state");

                    String authUrl = String.format(
                            "/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s",
                            clientId, URLEncoder.encode(redirectUri, StandardCharsets.UTF_8), scope, state
                    );
                    response.sendRedirect(authUrl);
                })
        );

配置文件添加社交客户端信息(application.yml)

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: 你的GitHub客户端ID
            client-secret: 你的GitHub客户端密钥
            scope: read:user,user:email
          google:
            client-id: 你的Google客户端ID
            client-secret: 你的Google客户端密钥
            scope: profile,email

404错误排查要点

  • 查看日志确认404的具体请求路径,检查是否是重定向地址未加入授权服务器白名单。
  • 确保授权服务器的/login端点可正常访问,默认表单登录页面无需额外配置。
  • 确认前后端端口无冲突,请求未发送到错误服务。

内容的提问来源于stack exchange,提问作者Kauã Pereira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:27:49