Spring Boot 2 如何启用一个非安全的 /health 端点。

6

我有一个Spring Boot 2项目,其中包含客户端和服务器身份验证,我想仅公开/actuator/health端点,以便无需进行任何身份验证。

我的初始WebSecurityConfigurerAdapter如下:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
    private void configureWithSsl(@NotNull HttpSecurity http) throws Exception {
        LOG.info("configuring access with ssl");
        http
                .csrf().disable()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and().x509()
                .and().userDetailsService(userDetailsService());
    }
...
}

以及 application.yaml 文件

server:
  port: 8443
  ssl:
    enabled: true
    key-store: 'paht/to/kestore/keystore.jks'
    key-store-password: 123456
    key-store-type: JKS
    client-auth: need
    trust-store: 'paht/to/truststore/truststore.jks'
    trust-store-type: JKS
    trust-store-password: 123456
    protocol: TLS
    enabled-protocols: TLSv1.2

我已经尝试过以下方法: 1. 将终端点的 'channel'配置为不安全。

    private void configureWithSsl(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .requiresChannel().requestMatchers(EndpointRequest.to("health")).requiresInsecure()
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and().x509()
                .and().userDetailsService(userDetailsService());
    }
  1. 为端点添加匹配器:
    private void configureWithSsl(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .requestMatchers(EndpointRequest.to("health")).permitAll()
                .anyRequest().authenticated()
                .and().x509()
                .and().userDetailsService(userDetailsService());
    }
  1. 在端点中添加忽略选项:
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().requestMatchers(EndpointRequest.to("health"));
}

我尝试了所有这些组合,但仍然出现问题。
curl -k  https://localhost:8443/actuator/health
curl: (35) error:1401E412:SSL routines:CONNECT_CR_FINISHED:sslv3 alert bad certificate

curl http://localhost:8443/actuator/health
Bad Request
This combination of host and port requires TLS.

我希望只有健康端点不受保护,其他执行器端点需要受保护,因此配置management.server.ssl.enabled=false无法解决问题...

编辑:

根据@Aritra Paul的答案,我也尝试了:

http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers( "/actuator/health/**").permitAll()
        .antMatchers( "/**").authenticated()
        .and().x509()
        .and().userDetailsService(userDetailsService());

但我仍然得到相同的结果。

不清楚你的意思是“非SSL”还是“没有Spring安全性”。 - chrylis -cautiouslyoptimistic-
我一直在尝试让所有的端点都通过https进行身份验证,并且/actuator/health端点不需要任何身份验证。我也尝试在原问题中澄清这一点。 - apines
你似乎没有理解证书错误和应用程序认证错误之间的区别。 - chrylis -cautiouslyoptimistic-
你介意详细解释一下吗?我在这方面的知识确实有限,很愿意学习。 - apines
1
你找到解决方案了吗? - Wee
显示剩余2条评论
3个回答

5

我曾经遇到过一个非常相似的情况,我们为端点添加了 X.509 认证,但想要保持 Spring 执行器端点的无身份验证状态。

使用 Spring 2.2.3 版本,你可以像你所做的那样将服务器配置为 ssl,但是可以在你的 management 配置中禁用 ssl(用于配置执行器端点),如下所示:

management:
  server:
    port: 8080
    ssl:
      enabled: false

通过这种简单的组合,我们可以在端口8080上使用无需身份验证的方式访问执行器端点,同时在端口8443上通过ssl访问其他端点。


0
我是这样解决的:
在实现了WebSecurityConfigurerAdapterSecurityConfig类中。
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.regexMatcher("^(?!(/actuator/)).*$")
            .csrf().disable()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .x509()
            .subjectPrincipalRegex("CN=(.*?)(?:,|$)")
            .userDetailsService(userDetailsService());

并且在 application.yaml 文件中

management:
  server:
    port: 8088
    ssl:
      enabled: false
  endpoint:
    health:
      probes:
        enabled: true
  health:
    livenessState:
      enabled: true
    readinessState:
      enabled: true

-1
我理解你想让actuator/health这个url对所有人开放,而其他的url则根据角色或授权控制访问。如果是这样,你可以尝试以下方式:
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                .antMatchers( "/actuator/health/**").permitAll()
                .antMatchers("/other-url/**").hasRole("your role")
                .authenticated();
    }

我已经编辑了我的问题,包括你写的内容,并做了一些修改:我需要x509(客户端和服务器证书),而且我不确定@EnableResourceServer是什么,似乎我没有导入该注释所需的依赖项。我需要那个注释来代替@EnableWebSecurity吗? - apines
WebSecurityConfigurerAdapterResourceServerConfigurerAdapter是两个不同的东西。你只需要替换configureWithSsl。我已经更新了我的答案。 - Aritra Paul
这就是我所做的,除了必须有x509()部分之外。 - apines
它仍然无法解决其他执行器端点的问题,例如/actuator/info等等... 我希望它们也能得到保护。 - apines
我在这里没有看到任何其他问题。只需交叉检查您的Maven依赖即可。 - Aritra Paul
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接