它没有 HTTP ok 状态 - Spring boot keycloak version 4.0.0 final behind haproxy

It does not have HTTP ok status - Spring boot keycloak version 4.0.0 final behind haproxy

我在使用 keycloak 验证的 spring 引导应用程序时遇到问题,我将此应用程序放在 haproxy 后面,并尝试在 spring 应用程序上完全禁用 cors 并在代理方,但是我仍然遇到cors问题。 “它没有 HTTP 正常状态”

注意我使用的是旧版本的 spring boot keycloak 插件,因为原始应用程序使用 spring 引导版本 1.5.10 请在附件中找到我探索过的一些配置选项:

案例 1:在 spring 应用上禁用 cors ------------------------------ ------------------

此设置 returns 响应预检时不存在 http 状态正常 header

 @Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;

public SecurityWithoutCsrfConfig() {
    super();
}

// Submits the KeycloakAuthenticationProvider to the AuthenticationManager
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
    keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
    auth.authenticationProvider(keycloakAuthenticationProvider);
}

@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
    return new KeycloakSpringBootConfigResolver();
}

// Specifies the session authentication strategy
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
    return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}

@Override
public void configure(final WebSecurity web) throws Exception {

    web.ignoring().antMatchers("/resources/**",
            "/v2/api-docs",
            "/swagger-ui.html",
            "/swagger2-ui.html",
            "/springfox/**",
            "/v2/swagger.json",
            "/_twilio/**",
            "/webjars/**",
            "/configuration/**",
            "/swagger-resources/**");
}

@Override
protected void configure(final HttpSecurity http) throws Exception {

    super.configure(http);

            http.csrf().disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("/mypath/**").hasAnyRole("USER")
            .antMatchers("/mypath_admin/**").hasAnyRole("USER_ADMIN", "ADMIN")      
                    .anyRequest().fullyAuthenticated()
                    .and().httpBasic().and().cors().disable();
    http.headers().cacheControl();
}

案例 2:在 spring 应用端设置 headers -------------------------- ----------------------

安全配置

@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;

public SecurityWithoutCsrfConfig() {
    super();
}

// Submits the KeycloakAuthenticationProvider to the AuthenticationManager
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
    keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
    auth.authenticationProvider(keycloakAuthenticationProvider);
}

@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
    return new KeycloakSpringBootConfigResolver();
}

// Specifies the session authentication strategy
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
    return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}

@Override
public void configure(final WebSecurity web) throws Exception {

    web.ignoring().antMatchers("/resources/**",
            "/v2/api-docs",
            "/swagger-ui.html",
            "/swagger2-ui.html",
            "/springfox/**",
            "/v2/swagger.json",
            "/_twilio/**",
            "/webjars/**",
            "/configuration/**",
            "/swagger-resources/**");
}

@Override
protected void configure(final HttpSecurity http) throws Exception {

    super.configure(http);

    http.csrf().disable()
     .authorizeRequests()
     .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
     .antMatchers("/mypath/**").hasAnyRole("USER")
     .antMatchers("/mypath_admin/**").hasAnyRole("USER_ADMIN", "ADMIN")  
     .anyRequest().fullyAuthenticated()
     .and().httpBasic();

    http.headers().cacheControl();
}

网络配置

public class WebConfig extends WebMvcConfigurerAdapter {

/**
 * Adds Cross Origin Resource Sharing filter
 * @return CorsFilter
 */
@Bean
public CorsFilter corsFilter() {

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("DELETE");
    config.addAllowedMethod("PATCH");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("swagger-ui.html")
            .addResourceLocations("classpath:/META-INF/resources/");

    registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/");
}

对于案例 2,我遇到了允许的来源 headers 的问题。我的 haproxy 配置是您可以在任何官方 haproxy 站点上找到的标准设置。 非常感谢对上述问题的任何解决方案或建议...... 最好是预检响应中 http 状态的解决方案。

为了进一步调试情况,我在我的安全配置 class 的配置方法中添加了一个记录器,因为这是我怀疑请求中断的地方

        LOG.info("  --executing: configure(HttpSecurity)");

事实上我在这个 class 中有一个记录器现在意味着更多的配置细节将被打印到应用程序的输出中,所以我构建了 jar,将它复制到服务器并且 运行我的 jar 文件。当我重新加载最初给我 cors 错误的请求时(http okay status not present on present flight)日志打印出一个 SSL 握手异常,这告诉我在我的应用程序配置中的某个地方它被设置为只期望通过 https 连接或安全端口。然而事实并非如此,我使用的是暴露在安全端口上的 haproxy,将连接转发到 jar 正在侦听的端口 (8080)。 因此,我仔细检查了整个应用程序的所有安全配置,并在我的应用程序属性中发现

的设置错误
keycloak.ssl-required=all

所以我删除了这个设置,部署了应用程序,瞧,问题避免了。希望这对遇到类似问题的任何人有所帮助。