Spring Boot Clients Not Deregistered from Spring Boot Admin when Spring Boot Instance Stopped - spring-boot

We have Spring Boot Admin Version-2.0.3 and corresponding Client Version.
Our spring boot instances are deployed to Pivotal Cloud Foundry.
Everything works great, until we deploy a new version of a spring boot instance. A new internal url is generated for the instance, and get registered to admin. But it didn't deregister the removed instance from the admin.
So it leaves spring boot admin in an inconsistent state. such as:
how can I make the registered instance deregister itself when it gets destryed.
I have tried setting:
spring.boot.admin.client.auto-deregistration = true
But it doesn't work as hoped.

The setting auto-deregistration=true causes your client application to send a http delete call to the server on endpoint /instances/{id}. Csrf checking must be disabled for this endpoint as well on the server. This configuration was missing in the sample securityconfiguration in the spring boot admin documentation. ( See https://github.com/codecentric/spring-boot-admin/issues/1251 )
To fix this, replace
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(adminContextPath + "/instances", adminContextPath + "/actuator/**");
With
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(
new AntPathRequestMatcher(adminContextPath + "/instances", HttpMethod.POST.toString()),
new AntPathRequestMatcher(adminContextPath + "/instances/*", HttpMethod.DELETE.toString()),
new AntPathRequestMatcher(adminContextPath + "/actuator/**")
);

Related

Spring Boot session is not created in Azure

When we deploy our Spring Boot app to Azure Web App, the JSESSIONID cookie is not created, and it looks like there is no session at all.
This is our Spring Security session config:
private void setSessionManagement(HttpSecurity http) throws Exception {
http.sessionManagement()
.enableSessionUrlRewriting(false)
.sessionFixation()
.migrateSession()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.invalidSessionStrategy(invalidSessionStrategy);
//.maximumSessions(1)
//.expiredSessionStrategy(expiredSessionStrategy);
}
When we run in locally in Docker/IntelliJ, it is created. Besides this, I have already set the ARR affinity 'On' under the Configuration > General settings, but still no luck.
Edit:
Found the issue, we had to update Spring Boot: 2.3.5.RELEASE -> 2.5.4
I am tried with latest Spring Boot version 2.5.4 I am not getting any issue. I can see the JSESSIONID cookie has created.
Seems like the some session issues has been fixed in the update. Release v2.5.4 ยท spring-projects/spring-boot
I hope your issue has fixed with latest version.

Access secured actuators from Spring Boot Admin with Kubernetes Service Discovery

I've got a Spring Boot Admin application which uses a Kubernetes Service Discovery to get the Spring Boot client applications.
spring:
cloud:
kubernetes:
discovery:
all-namespaces: true
service-labels:
springbootadmin: true
reload:
enabled: true
period: 60s
strategy: refresh
Without secured actuator endpoints this works fine.
But as soon as the client actuator endpoints are protected by basic auth this does not work any more. The Spring Boot Admin Documentation describes how to add the authentication data to the Spring Boot Admin Server bit it does not describe how to provide this when the services are discovered via Kubernetes.
I've tried these configurations. But they don't work:
Spring Boot Admin Docs: spring.boot.admin.instance-auth.default-user-name + password
Spring Boot Admin Tutorial spring.boot.admin.client.instance.metadata.user.name + password
I also found an answer which describes how to configure the credentials in the Kubernetes annotations. This works but I would prefer to configure the credentials in the Spring Boot Admin configuration (where I can use Secrets) and not separately for each service in the Kubernetes configuration as an unsecure label.
I think I have to inject the credentials in the Service Discovery metadata. But how?
EDIT
I've examined the service discovery and found no auth configuration options which could be provided:
class KubernetesDiscoveryProperties.Metadata
class de.codecentric.boot.admin.server.cloud.discovery.DefaultServiceInstanceConverter
It might be an option to add a custom header to the requests that are sent by SBA to the clients:
#Bean
public HttpHeadersProvider customHttpHeadersProvider() {
return (instance) -> {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", "Basic bXlTcGVjaWFsVXNlcm5hbWU6bXlTcGVjaWFsUGFzc3dvcmQ=");
return httpHeaders;
};
}
The authentication can be set by these settings:
spring:
boot:
admin:
instance-auth:
default-user-name: user
default-password: pw
These settings are read by the Configuration Class AdminServerInstanceWebClientConfiguration which instantiates a bean basicAuthHttpHeadersProvider.

Accessing tomcat management page from Spring tool set 4

I have developed a Camel Rout using Spring. I used the STS4 IDE to develop the same.
When I started the application using Run As-> Spring Boot App, the application starts and also I can see from the logs that the route is started.
My route is a basic app, the exposes a rest endpoint and logs a Hello World
#Override
public void configure() throws Exception {
restConfiguration()
.enableCORS(true)
.apiContextPath("/api-doc")
.apiProperty("api.title", "Test REST API")
.apiProperty("api.version", "v1")
.apiContextRouteId("doc-api")
.component("servlet")
.bindingMode(RestBindingMode.json);
rest("/api/")
.id("api-route")
.consumes("application/json")
.get("/test")
.to("direct:log");
from("direct:log")
.id("log")
.log(LoggingLevel.INFO,"Test successful");
}
What I am expecting is that if I do localhost:8080/api/test, i will see some logs "Test Susccessful" in the Tomcat logs. I am using tomcat 9, Instead what I get WhiteLable error. I thought there is an issue with my code so I tried localhost:8080 and i was expecting the Tomcat Management server to open. Even that is not working.
I am not starting Tomcat separately. What I am doing is Run As-> Spring Boot App and I guess it is calling the embedded tomcat.
Credit for this answer goes to #Bedla. I had to add camel in the URL path http://localhost:8080/camel/api/test

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.

Connect secured Client with Spring Boot Admin Security

Can someone guide me how can I connect my secured client with the spring boot admin application?
Scenario: I have a spring boot application (client) with spring security and spring-actuator enabled. The actuator endpoints are secured and for this I have the following (working) configuration in my web security config:
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
auth.inMemoryAuthentication().withUser("Test-Actuator").password("Test-Baby").roles("ADMIN", "ACTUATOR");
}
Now I want to integrate the Spring Boot Admin Application in our environment. I set up a simple application with spring-boot-admin-server and spring-boot-admin-server-ui enabled. In the application.properties file I provide the following properties:
spring.boot.admin.username=test
spring.boot.admin.password=test
these are for the server admin, right?
spring.boot.admin.client.metadata.user.name=Test-Actuator
spring.boot.admin.client.metadata.user.password=Test-Baby
these are for the client, right?
Now when I run the applications I get the following error from the client: Failed to register application as Application [...] at spring-boot-admin ([...]) 401 null
I call the spring boot admin page and get a HttpBasic Authentication Pop Up. No credentials from above work for this Pop Up.
Note: If I disable the security in the client application.properties file it works but (like expected) the client doesn't work anymore.

Resources