securing jolokia actuator endpoint not working when accessing through hawt.io - spring-boot

I've got hawtio 2.1.0 installed connecting to the jolokia endpoint exposed by a spring boot 2.0.5 app.
My app yaml contains
management:
endpoints:
enabled-by-default: true
web:
exposure:
include: "jolokia"
jmx:
exposure:
exclude: "*"
endpoint:
jolokia:
enabled: true
config:
debug: true
In addition I have a filter
#Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
.hasRole("ADMIN")
.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class))
.permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint())
.fullyAuthenticated()
.and().httpBasic();
}
When I access the jolokia actuator endpoint in my browser it correctly asks me for my credentials.
So using this method the endpoints are secured.
When I connect to the jolokia endpoint through the hawt.io web app I don't need to provide any credentials. It makes no differnence if hawt.io is running on a remote or on the local maschine the spring boot app is running on. Hawt.io is able to get all the MBean infos via jolokia.
How can that be?
Hawt.io somehow circumvents the securing of the jolokia actuator endpoint.
Any ideas why this is or how I can secure the jolokia actuator endpoint so that even hawt.io prompts for the credentials?
Thanks a lot in advance!
Cheers
Oliver

Related

Unable to access actuator endpoints when deployed on Google App Engine 11

I have an inherited spring boot application that was happily living on GAE 8 standard running on jetty. We are in the process of upgrading it to GAE 11 standard.
Based the Differences between Java 8 and Java 11/17 we determined that we would try to Migrating to Java 11/17 with bundled services and followed the instructions to Access bundled services using the App Engine APIs JAR..
The appengine-web.xml and pom.xml were updated as specified above, although we do not have a web.xml, we needed <app-engine-apis>true</app-engine-apis> to prevent some errors on start up because we previously used <sessions-enabled> to secure actuator endpoints. We do not use an app.yaml yet.
There are some release scripts in the code that suggest I should be able to access the actuator endpoints for smoke testing our DEV project to compare against our production endpoints prior to release, for instance /_ah/health, so that is where I am starting to validate my upgrade. So far...
I can access /_ah/health in our current version in production (GAE
8).
I can access /_ah/health in our current version in development
(GAE 8).
I can access /_ah/health locally on http:8080 after
clean package appengine:run (GAE 11, branch), Google App Engine
Maven plugin (deploy)
I cannot access /_ah/health and get 404 Error: Not Found when deployed to out dev (GAE 11, branch)
I've turned up the logs. I can see that is falls through several security filters but I still get a 404:
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
So I am thinking this is related to the Security Configuration.
The intention is to allow the /health and /health/** for all but secure all other actuator endpoints with basic authentication (configured user/pass) in application.yml
Any help would be appreciated. Here is what I think are some valid config files. notes and logs...
All of the necessary work to upgrade the underlying spring boot application from java 8 to 11 (as suggested by many articles/checklists on the web) was completed many months ago and now we are compiling to java 11 and upgrading our GAE deployment.
appengine-web.xml updated for java 11
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<service>my-api</service>
<runtime>java11</runtime>
<instance-class>F4</instance-class>
<app-engine-apis>true</app-engine-apis>
<!-- To allow securing actuator endpoints with a login -->
<sessions-enabled>true</sessions-enabled>
<automatic-scaling>
<min-idle-instances>1</min-idle-instances>
</automatic-scaling>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
</system-properties>
</appengine-web-app>
application.yml
# ...
management:
endpoints:
web:
# GAE Standard Runtime looks for health checks under /_ah - not sure if valid any more
base-path: /_ah
exposure:
include: env,health
health:
probes:
# This enables base-path/health/liveness and base-path/health/readiness
enabled: true
# This health check will fail on GAE Standard Runtime
diskspace:
enabled: false
spring:
security:
user:
name: foo
password: bar
roles: ADMIN
# ...
SecurityConfig.java
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(final HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable()
.authorizeRequests()
.requestMatchers(EndpointRequest.to("health")).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ADMIN")
.antMatchers("/**").anonymous()
.and().httpBasic();
}
}
Application.java
#EnableWebSecurity
#SpringBootApplication
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
// ...
}
ServletInitializer.java
Public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
As confirmed in the comments section, using an older working version of Cloud SDK (in this case v371.0.0) resulted in being able to successfully access the endpoints again.
Additionally, the issue has already been reported in the issue tracker: App Engine Standard Java 8: 404 Not Found

How to enable health in Spring Boot Actuator

I have to check whether my service / app works or not.
I've added dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.6.2</version>
</dependency>
and also tried to add management.endpoint.health.show-details: always to application.yml but it didn't help.
I tried to go to http://localhost:8080/actuator/health, http://localhost:8080/health but it returned 404 error.
You can try this code on your application.yaml. This is worked for Spring boot 2.6.7.
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: health
As you see, you have 404 both on
http://localhost:8080/actuator/health
and
http://localhost:8080/health
Reason for this is not because security is enabled, if security was enabled you will get 401 or 403.
You probably need to expose actuator endpoints in application.yaml file.
Something like this:
management:
endpoints:
web:
exposure:
include: "health,info"
And if you have security enabled, you need to write you own SecurityFilterChain implementation in which you will disable security on all Actuator endpoints, or in your case only on those that you exposed in your application.yaml file.
Example:
#Configuration
class ActuatorSecurityAutoConfiguration {
#Bean
SecurityFilterChain
surpassingActuatorSecurityFilterChain(HttpSecurity
httpSecurity) throws Exception {
return httpSecurity
.requestMatcher(EndpointRequest.toAnyEndpoint())
.authorizeRequests()
.anyRequest()
.permitAll()
.and().build();
}
}
By default Spring boot enables security for all actuator endpoints
You can disable that feature using below property
management.security.enabled=false
Henceforth, try to run the application and hit the endpoint
http://localhost:8080/actuator

Spring boot 2.1.x how to secure Actuator end points with basic auth

I am trying to build a spring boot application and wanted to leverage the Actuator features, but I want to secure the end points of Actuator /health,/shutdown etc. I have the below configurations which does not seem to work. I.e., application never prompts for credentials or when hit from post man does not give 403. I tried various ways, even the one from spring documentation. Can any one please help with this. Again this is spring boot 2.1.x. I know there is a configuration that can be made in application.yml in the previous version of spring
#Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class, InfoEndpoint.class, HealthEndpoint.class,
MetricsEndpoint.class))
.hasRole("ENDPOINT_ADMIN").requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.authenticated().and().httpBasic();
}
application.yml
spring:
security:
user:
name: admin
password: admin
roles:
- ENDPOINT_ADMIN
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
shutdown:
enabled: true
health:
show-details: when-authorized
roles:
- ENDPOINT_ADMIN
mappings:
enabled: true
This code can serve you as a reference to achieve BasicAuth for Actuator Endpoints Spring Boot 2.X. This is not the exact code. While Extending WebSecurityConfigurerAdapter you have to configure AuthenticationManagerBuilder to assign roles and passwords for the roles. Here I am using "noop" password encoder you can use a different one to provide more security.
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("ROLE_USER").password("{noop}" + "USER_PWD").roles("USER").and()
.withUser("ROLE_ADMIN").password("{noop}" + "ADMIN").roles("ADMIN", "USER");
}
Once AuthenticationManagerBuilder is configured now configure HttpSecurity by disabling csrf. Below code requires authentication for metrics alone using any role. You can customize according to the end points you need to authenticate. Make sure you exclude base url of Rest Controller from this Authentication. You can insert authorizeRequests().antMatchers("/baseurl").permitAll().and() in the below configuration code to achieve that. Below is an example to configure HttpSecurity.
protected void configure(Httpsecurity http) {
http.csrf().authorizeRequests().requestMatchers(EndpointRequest.to(MetricsEndpoint.class))
.hasANyRole("ADMIN","USER").and().authorizeRequests().and().httpBasic();
}

Spring boot admin: Full authentication is required to access this resource

we are using netflix oss for reverse proxying and security of microservices, we are following the jhipster pattern mentioned here https://www.jhipster.tech/microservices-architecture/, where request from UI application goes to gateway which is Api Gateway and it proxies the request to our backend microservices , we are using jwt for authentication, we wanted a dashboard to monitor our microservices and api gateway which registers with eureka server , we started a separate spring boot admin server so that it registers with eureka server and poll microservices and gateway for metrics endpoint but we are getting exception
Full authentication is required to access this resource
which is thrown by filters which are filtering for jwts at both api gateway and microservices level,
we also tried disabled
management.security.enabled: false
but still no luck ,can some one please help to guide what changes i need to make to enable spring boot admin to successfully poll the microservices and api gateway?
I tried the following approach
firstly i enabled web.ignoring().antMatchers("/actuator/**"), so that actuator endpoints are ignored by spring security but this approach will risk my api's
Second idea:
if i enable 2 filters in spring security , the first filter would be for spring boot admin with basic authentication for actuator endpoints and second filter will be of my jwt authentication for rest all api's and downstream api's not sure will it be feasible?
i enabled the 2 filters one filter for actuator end points and 1 filter for api's but these filters are working perfectly but not able to connect to SBA
public class SpringSecurityAdminFilter extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
String password = passwordEncoder().encode("xxxx");
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).withUser("sam").password(password).roles("ADMIN");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/**").hasRole("ADMIN")
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.
}
}
i enabled basic authentication for spring boot admin server added the property in microservices
eureka.instance.metadata-map.user.name:
eureka.instance.metadata-map.user.password:
now actuator endpoints are protected by basic authentication
I have had a similar issue. On my spring boot application we had a cors filter to block Http Head requests. So head requests cannot be accepted from spring boot admin.
Check maybe filter is blocking HEAD Http requests .
Setting management.security.enabled=false in the application.properties also necessary.

Consul health check pass by Spring security filter

I created Spring cloud application using consul as services discovery/registry.
I have configured my spring security as follow:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(myEntryPoint());
http
.authorizeRequests()
.antMatchers("/images/**").permitAll()
.antMatchers("/modules/**").permitAll()
.antMatchers("/vendor/**").permitAll()
.antMatchers("/views/**").permitAll()
.antMatchers("/index.html").permitAll()
.regexMatchers("/health").permitAll()// consul check health
.antMatchers("/api/**").authenticated()
.antMatchers("/**").permitAll();
http // login configuration
.addFilterAfter(springSecurityFilter(), BasicAuthenticationFilter.class);
http //logout configuration
.logout()
.logoutSuccessHandler(logoutHandler());
http.csrf().disable();
}
Normally, using this filter spring consul health check doesn't pass by this filter (public access).
But consul health check consul pass by filter.
If I use the following url I'm redirected to the authentication page:
https://localhost:8181/health
By default consul from spring-cloud-starter-consul-discovery use /actuator/health to check health.
When spring-security is used, should provide & permit that path.
Steps:
Permit /actuator/health in spring-security, then consul could perform the health check.
e.g
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/hello", "/authenticate", "/actuator/health")
.permitAll().
Add actuator dependency, if not yet.
Expose endpoints
e.g
management:
endpoints:
web:
exposure:
include: "*"

Resources