当前位置: 首页 > 知识库问答 >
问题:

绕过CAS从Spring boot应用程序获取未/安全的健康信息

濮阳繁
2023-03-14
@Configuration
@EnableWebSecurity
public class CASWebSecurityConfig extends WebSecurityConfigurerAdapter {
http.authorizeRequests().antMatchers("/health/**").permitAll();
    null
management.security.enabled: true
endpoints.health.sensitive: false

但我对如何配置凭据有个问题...在http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-monitoring.html#production-ready-sensition-endpoints之后,我在配置html" target="_blank">文件中添加了以下内容:

security.user.name: admin
security.user.password: secret

但它不起作用--当我不放属性时,我看不到日志中生成的密码。

所以我试着放一些自定义属性,比如

healthcheck.username: healthCheckMonitoring
healthcheck.password: healthPassword
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth,
                            CasAuthenticationProvider authenticationProvider) throws Exception {

    auth.inMemoryAuthentication().withUser(healthcheckUsername).password(healthcheckPassword).roles("ADMIN");
    auth.authenticationProvider(authenticationProvider);
} 
   http.authorizeRequests()
        .antMatchers("/health/**").hasAnyRole("ADMIN")
        .and().httpBasic()
        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and().csrf().disable();

如何调整Spring Security配置以使其正常工作?我有一种感觉,我应该以某种方式链接配置,CAS配置首先允许请求纯粹基于URL通过,这样请求就会命中第二个配置,如果提供了凭据,该配置将执行基本的http身份验证,或者让请求命中未经身份验证的endpoint,这样我就得到了“仅状态”的结果。但同时,我认为Spring Boot可以正确地管理这一点,如果我适当地配置它…

谢了!

共有1个答案

沈冠宇
2023-03-14

解决方案不是很好,但到目前为止,这对我来说是有效的:

在我的配置中(只有相关代码):

@Configuration
@EnableWebSecurity
public class CASWebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    //disable HTTP Session management
    http
        .securityContext()
        .securityContextRepository(new NullSecurityContextRepository())
        .and()
        .sessionManagement().disable();

    http.requestCache().requestCache(new NullRequestCache());

    //no security checks for health checks
    http.authorizeRequests().antMatchers("/health/**").permitAll();

    http.csrf().disable();

    http
        .exceptionHandling()
        .authenticationEntryPoint(authenticationEntryPoint());

    http // login configuration
        .addFilter(authenticationFilter())
        .authorizeRequests().anyRequest().authenticated();
}
}

然后我添加了一个特定的过滤器:

@Component
public class HealthcheckSimpleStatusFilter  extends GenericFilterBean {

private final String AUTHORIZATION_HEADER_NAME="Authorization";

private final String URL_PATH = "/health";

@Value("${healthcheck.username}")
private String username;

@Value("${healthcheck.password}")
private String password;

private String healthcheckRole="ADMIN";

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    HttpServletRequest httpRequest = this.getAsHttpRequest(request);

    //doing it only for /health endpoint.
    if(URL_PATH.equals(httpRequest.getServletPath())) {

        String authHeader = httpRequest.getHeader(AUTHORIZATION_HEADER_NAME);

        if (authHeader != null && authHeader.startsWith("Basic ")) {
            String[] tokens = extractAndDecodeHeader(authHeader);
            if (tokens != null && tokens.length == 2 && username.equals(tokens[0]) && password.equals(tokens[1])) {
                createUserContext(username, password, healthcheckRole, httpRequest);
            } else {
                throw new BadCredentialsException("Invalid credentials");
            }
        }
    }
    chain.doFilter(request, response);
}

/**
 * setting the authenticated user in Spring context so that {@link HealthMvcEndpoint} knows later on that this is an authorized user
 * @param username
 * @param password
 * @param role
 * @param httpRequest
 */
private void createUserContext(String username, String password, String role,HttpServletRequest httpRequest) {
    List<GrantedAuthority> authoritiesForAnonymous = new ArrayList<>();
    authoritiesForAnonymous.add(new SimpleGrantedAuthority("ROLE_" + role));
    UserDetails userDetails = new User(username, password, authoritiesForAnonymous);
    UsernamePasswordAuthenticationToken authentication =
        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

private HttpServletRequest getAsHttpRequest(ServletRequest request) throws ServletException {
    if (!(request instanceof HttpServletRequest)) {
        throw new ServletException("Expecting an HTTP request");
    }
    return (HttpServletRequest) request;
}

private String[] extractAndDecodeHeader(String header) throws IOException {
    byte[] base64Token = header.substring(6).getBytes("UTF-8");

    byte[] decoded;
    try {
        decoded = Base64.decode(base64Token);
    } catch (IllegalArgumentException var7) {
        throw new BadCredentialsException("Failed to decode basic authentication token",var7);
    }

    String token = new String(decoded, "UTF-8");
    int delim = token.indexOf(":");
    if(delim == -1) {
        throw new BadCredentialsException("Invalid basic authentication token");
    } else {
        return new String[]{token.substring(0, delim), token.substring(delim + 1)};
    }
}

}
 类似资料:
  • 我有一个基于SpringBoot的web应用程序,它公开了一个Consor健康指示器bean 在进一步检查后,我发现了负责获取所有可用指标的下面片段(HealthEndpoint Configuration.java): 在这里设置一个断点,我看到ConsultHealthIndicator bean确实没有列在applicationContext的输出中。getBeansOfType(Healt

  • 我最初的是: 和 我试过了:1。将“通道”配置为endpoint不安全 null null 根据@Aritra Paul的回答,我也试过: 但我还是得到同样的结果。

  • 我有一个基于SpringBoot的web应用程序,它公开了一个Consult health indicator bean。 该bean由SpringBoot的autoconfiguration正确创建和初始化,但是,尽管关联的配置属性“Management.health.consul.Enabled”设置为true,但指示器并未显示在执行器健康endpoint中: 经过进一步检查,我发现了负责获取

  • 问题内容: 是否可以使用Java从Windows Vista计算机中获取已安装应用程序的列表(如来自卸载程序的列表)? 问题答案: 不是解决方案,而是解决方法! 如果没有外部API的支持,则无法使用Java SDK获取Windows本机信息。代替使用外部API(主要由LGPL许可且未完全开放),我们可以使用shell命令来获取相同的信息。 要获取已安装的软件列表,请使用ProcessBuilder

  • 我正在尝试修改我在网上多个地方找到的KeyClope和Spring Boot教程中的代码(代码看起来已经被复制)。在任何情况下,尽管keybeapt保护正确的url,Spring Security性也很方便,但在尝试检索主体时,它返回为null。这是我的申请表。属性文件: 这是我的安全配置。java文件(教程中的原始文件): 我的web控制器如下所示: 最后,这是我的Maven配置,以防它有所不同

  • 我正在使用运行在非8080端口上的Spring Boot web应用程序。我需要编写一个rest API来检查应用程序以及底层数据库的健康状况。 关于同样的,我已经看了这篇文章:如何在Spring启动健康中添加自定义健康检查?,但没有找到任何具体的实现。 实际上我想做以下工作: > 所有下游API的健康检查 DB是否工作正常 那么任何人都可以帮我吗?谢谢。