4
votes

We are using token-based authentication (with Spring Security) in our Spring Boot 2 application. Now I'm introducing Spring Boot Actuator to it. I would like to configure the /health endpoint to be visible without any permissions but to show health checks details only when authorized.

I found the property management.endpoint.health.show-details=when_authorized which should be helpful but now I'm fighting with the Spring Security configuration to allow everybody to see:

{
  "status": "UP"
}

under /actuator/health while users authorized with token should see:

{
  "status": "UP",
  "details": { ... }
}

Did you face a similar problem? How did you handle it?

1
How application behave when you access this endpoint with and without authentication?Kamil W
Now, when the parameter management.endpoint.health.show-details=when_authorized is set and I'm turning on authentication for this endpoint then I see the details. But I cannot enter without authentication. When I turn off auth for the endpoint and the when_authorized is set, I do not see details. So the param is working correctly. But I cannot figure out how to set /actuator/health endpoint to be available both with and without authentication...Piotr Pradzynski
@PiotrPradzynski how did you solved this? I am also stuck in the same place!iamkdblue

1 Answers

2
votes

OK, now I understand, if you turn off security in your application and keep management.endpoint.health.show-details=when_authorized you are getting just status field? If I'm right it's not an issue, take a look in spring class HealthWebEndpointResponseMapper into map method. As I found out this method overwrites (remove details field from the response) if condition in if is true:

public WebEndpointResponse<Health> map(Health health, SecurityContext securityContext,
        ShowDetails showDetails) {
    if (showDetails == ShowDetails.NEVER
            || (showDetails == ShowDetails.WHEN_AUTHORIZED
                    && (securityContext.getPrincipal() == null
                            || !isUserInRole(securityContext)))) {
        health = Health.status(health.getStatus()).build();
    }
    Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
    return new WebEndpointResponse<>(health, status);
}

In your case, I guess you have set an above-mentioned property to when_authorized also you have turned off authentication, so the principal is null. Not sure if I'm right, but I hope I gave you a clue. :)