spring-bootjolokia

Cannot access a Jolokia endpoint with spring security on


I have Spring Boot 3.1.5 and inside yaml I have:

management:
  security:
    enabled: false
  endpoint:
    metrics.enabled: true
    httptrace.enabled: true
    shutdown.enabled: true
  endpoints:
    web.exposure.include: metrics, health, info, httptrace, jolokia
    jmx.exposure.include: health

I also have spring security on cp, and I think that I have enabled the path correctly:

@Bean
 public SecurityFilterChain getSecurityFilterChain(HttpSecurity http) throws Exception {

        return http.csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(
                        (requests) ->
                                requests.requestMatchers(HttpMethod.GET,
                                                Stream.concat(
                                                                Arrays.stream(AUTH_WHITELIST),  //{"/actuator/**"};
                                                                Arrays.stream(OPEN_API_WHITELIST)) //other swagger endpoints etc
                                                        .toArray(String[]::new))
                                        .permitAll()
                                        .anyRequest()
                                        .authenticated())
                .sessionManagement(
                        session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .exceptionHandling(
                        httpSecurityExceptionHandlingConfigurer ->
                                httpSecurityExceptionHandlingConfigurer.authenticationEntryPoint(
                                        new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
                .csrf()
                .disable()
                .logout()
                .disable()
                .build();
    }

I get 401 at http://localhost:8080/actuator/jolokia

I also added a bean as suggested on the docs:

@Bean
    public ServletRegistrationBean<AgentServlet> jolokia() {
        ServletRegistrationBean<AgentServlet> jolokiaServlet = new ServletRegistrationBean<>(new AgentServlet(), "/jolokia/*");
        jolokiaServlet.setLoadOnStartup(0);
        jolokiaServlet.setAsyncSupported(true);
        jolokiaServlet.setInitParameters(Map.of(ConfigKey.DEBUG.getKeyValue(), "true"));
        jolokiaServlet.setInitParameters(Map.of(ConfigKey.AGENT_DESCRIPTION.getKeyValue(), "Spring Servlet Jolokia Agent"));
        return jolokiaServlet;
    }

Don't understand this log line:

[o.a.c.c.C.[Tomcat].[localhost].[/]] SID= CID= [restartedMain] correlationId= channel= externalReferenceId= jolokia: No access restrictor found, access to any MBean is allowed

Related with:

https://github.com/spring-projects/spring-boot/issues/37568


Solution

  • You should use org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest to secure Actuator endpoints:

        @Bean
        public SecurityFilterChain getSecurityFilterChain(HttpSecurity http) throws Exception {
            return http.csrf(AbstractHttpConfigurer::disable)
                    .authorizeHttpRequests(
                            (requests) ->
                                    requests.requestMatchers(EndpointRequest.toAnyEndpoint())
                                    .permitAll().requestMatchers(HttpMethod.GET, OPEN_API_WHITELIST).permitAll()
                                    .anyRequest()
                                    .authenticated())
                    .sessionManagement(
                            session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                    .exceptionHandling(
                            httpSecurityExceptionHandlingConfigurer ->
                                    httpSecurityExceptionHandlingConfigurer.authenticationEntryPoint(
                                            new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
                    .csrf()
                    .disable()
                    .logout()
                    .disable()
                    .build();
        }
    

    Your previous attempt was applying Spring MVC @RequestMapping matching rules which do not apply to Actuator. Using EndpointRequest also removes the need to hardcode /actuator in the path and will automatically adapt to changes to the Actuator's path.

    You should also remove the registration of the AgentServlet bean. It isn't needed when you're using Spring Boot's Actuator, as you are. This is explained in the Jolokia documentation where it says that, when you have a dependency on spring-boot-starter-actuator you "can run a Spring Boot application without single Jolokia bean configuration".