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

Spring OAuth2 Server仅127.0.0.1可跳转redirect_uri,localhost失败

Spring Authorization Server 登录后 localhost:4200 跳转错误,127.0.0.1:4200 正常

我按照Spring官方文档配置了OAuth2授权服务器,Angular客户端运行在4200端口。账号密码验证通过后,用127.0.0.1:4200访问Angular能正常跳转到redirect_uri,但用localhost:4200访问就会跳转到错误页面。

Spring 配置代码

@Bean
    @Order(1)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
            .oidc(Customizer.withDefaults());   // Enable OpenID Connect 1.0
        http
                // Redirect to the login page when not authenticated from the
                // authorization endpoint
                .exceptionHandling((exceptions) -> exceptions
                        .authenticationEntryPoint(
                                new LoginUrlAuthenticationEntryPoint("/login"))
                )
                // Accept access tokens for User Info and/or Client Registration
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);

        return http.build();
    }

    @Bean
    @Order(2)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
            throws Exception {
        http
                .authorizeHttpRequests((authorize) -> authorize
                        .anyRequest().authenticated()
                )
                // Form login handles the redirect to the login page from the
                // authorization server filter chain
                .formLogin(Customizer.withDefaults());

        return http.build();
    }

    @Bean
    public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
        RegisteredClient registeredClient = RegisteredClient.withId("bakcup-ui")
                                                            .clientId("backup-ui")
                                                            .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
                                                            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                                                            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                                                            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                                                            .redirectUri("http://localhost:4200")
                                                            .redirectUri("http://127.0.0.1:4200")
                                                            .scope(OidcScopes.OPENID)
                                                            .scope(OidcScopes.PROFILE)
                                                            .clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())
                                                            .build();

        // Save registered client in db as if in-memory
        JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
        registeredClientRepository.save(registeredClient);


        return registeredClientRepository;
    }

Angular 端配置(使用angular-oauth2-oidc)

export const authConfig: AuthConfig = {
    clientId: 'backup-ui',
    issuer: 'https://localhost:9000',
    redirectUri: window.location.origin,
    responseType: 'code',
    scope: 'openid profile',
    strictDiscoveryDocumentValidation: false,
}

错误URL(localhost访问时跳转的地址)

localhost:9000/error?response_type=code&client_id=backup-ui&state=M09hSHdSdC5KSlRfOGlLNDZWa1NQbE05TDFRamJ6NGtwUDludUk0blM1Y1dO&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=openid%20profile&code_challenge=_LU-Ou9Gr_53_LGDKTz36bJddFr2gndknIrZoC03ZJo&code_challenge_method=S256&nonce=M09hSHdSdC5KSlRfOGlLNDZWa1NQbE05TDFRamJ6NGtwUDludUk0blM1Y1dO&continue

即使使用GitHub上的Spring Authorization Server示例代码也存在同样问题。


问题原因与解决方案

原因分析

Spring Authorization Server 默认对重定向URI做精确匹配,核心问题在于:

  1. 注册的重定向URI仅为根路径http://localhost:4200,但Angular客户端实际跳转时可能携带额外路径(比如登录前的页面路径),导致请求的redirect_uri与注册项不匹配;
  2. localhost和127.0.0.1虽指向同一机器,但在OAuth2校验逻辑中属于不同主机名,若会话上下文或请求头存在差异,也会触发校验失败。

解决方案

  1. 添加带通配符的重定向URI
    修改Spring注册客户端的代码,给localhost:4200和127.0.0.1:4200添加路径通配符,覆盖所有可能的跳转路径:

    .redirectUri("http://localhost:4200/**")
    .redirectUri("http://127.0.0.1:4200/**")
    

    注:**是Spring Authorization Server支持的路径通配符,仅适用于路径部分,不能用于主机名或端口。

  2. 显式指定客户端回调路径
    Angular端可显式固定回调路径(比如http://localhost:4200/callback),同时在Spring注册对应的URI,避免window.location.origin动态变化导致的不匹配:

    redirectUri: 'http://localhost:4200/callback',
    
  3. 开发环境临时调整(不推荐生产)
    若仅为开发测试,可关闭重定向URI的严格校验,允许动态注册:

    .clientSettings(ClientSettings.builder()
        .requireAuthorizationConsent(false)
        .redirectUriRegistrationAllowed(true)
        .build())
    

    生产环境必须禁用此配置,防止安全风险。

  4. 统一开发环境访问地址
    开发时固定使用localhost:4200或127.0.0.1:4200访问Angular应用,避免跨主机名的会话问题。


内容的提问来源于stack exchange,提问作者Mtyz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:40:54