I've been trying to setup Spring Boot Admin Server with a client using basic security configuration for a couple days now. Unfortunately I'm unable to get the client to authenticate with the server. I've tried a variety of examples and am at the point where I'm wondering if this is just a bug with the current release of the Spring Boot Admin.
Server application.properties
spring.security.user.name=admin
spring.security.user.password=admin
Server build.gradle
plugins {
id 'groovy'
}
group 'edu.wsu.it.esg-apps'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:latest.release'
compile 'de.codecentric:spring-boot-admin-starter-server:2.1.6'
compile 'org.springframework.boot:spring-boot-starter-web:2.1.7.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-security:2.1.7.RELEASE'
compile 'de.codecentric:spring-boot-admin-server-ui-login:2.1.6'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
SecuritySecureConfig.groovy
package admin.security
import de.codecentric.boot.admin.server.config.AdminServerProperties
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
@Configuration
class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath
SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath()
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler()
successHandler.setTargetUrlParameter("redirectTo")
successHandler.setDefaultTargetUrl(adminContextPath + "/")
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
// @formatter:on
}
}
SpringBootAdminApplication.groovy
package admin
import de.codecentric.boot.admin.server.config.EnableAdminServer
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.Configuration
@Configuration
@EnableAutoConfiguration
@EnableAdminServer
class SpringBootAdminApplication {
static void main(String[] args){
SpringApplication.run(SpringBootAdminApplication.class,args)
}
}
Client application.properties
server.port=8081
logging.level.root=DEBUG
spring.boot.admin.client.url=http://localhost:8080
spring.boot.admin.client.username=admin
spring.boot.admin.client.password=admin
spring.boot.admin.client.api-path=instances
management.endpoints.web.exposure.include=*
management.endpoints.jmx.exposure.include=*
management.endpoint.health.show-details=always
spring.security.user.name=client
spring.security.user.password=client
spring.boot.admin.client.instance.metadata.user.name=${spring.security.user.name}
spring.boot.admin.client.instance.metadata.user.password=${spring.security.user.password}
Client build.gradle
plugins {
id 'groovy'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
}
group 'edu.wsu.it.esgapps'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
compile "org.codehaus.groovy:groovy-all:latest.release"
compile "de.codecentric:spring-boot-admin-starter-client:2.1.6"
compile "org.springframework.boot:spring-boot-starter-security:2.1.7.RELEASE"
compile "org.springframework.boot:spring-boot-starter-web:2.1.7.RELEASE"
compile 'org.springframework.boot:spring-boot-starter-actuator:2.1.7.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-thymeleaf:2.1.7.RELEASE'
// compile 'org.springframework.cloud:spring-cloud-config-client:latest.release'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
client application.groovy
package edu.wsu.it.esgapps
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
class Application {
static void main(String[] args){
SpringApplication.run(Application.class,args)
}
}
At this point I'm at a loss. 90% of the configuration and classes are copy paste from reported working examples. I receive the following messages in the logs after firing up the client.
2019-11-24 21:06:36.021 DEBUG 20980 --- [gistrationTask1] o.s.web.client.RestTemplate : HTTP POST http://localhost:8080/instances
2019-11-24 21:06:36.021 DEBUG 20980 --- [gistrationTask1] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2019-11-24 21:06:36.021 DEBUG 20980 --- [gistrationTask1] o.s.web.client.RestTemplate : Writing [Application(name=spring-boot-application, managementUrl=http://ITS-ESG-T2-3025.ad.wsu.edu:8081/actuator, healthUrl=http://ITS-ESG-T2-3025.ad.wsu.edu:8081/actuator/health, serviceUrl=http://ITS-ESG-T2-3025.ad.wsu.edu:8081/)] as "application/json"
2019-11-24 21:06:36.024 DEBUG 20980 --- [gistrationTask1] s.n.www.protocol.http.HttpURLConnection : sun.net.www.MessageHeader@1715607e8 pairs: {POST /instances HTTP/1.1: null}{Accept: application/json}{Content-Type: application/json}{Authorization: Basic YWRtaW46YWRtaW4=}{User-Agent: Java/11.0.1}{Host: localhost:8080}{Connection: keep-alive}{Content-Length: 329}
2019-11-24 21:06:36.030 DEBUG 20980 --- [gistrationTask1] s.n.www.protocol.http.HttpURLConnection : sun.net.www.MessageHeader@17d95de411 pairs: {null: HTTP/1.1 401}{Set-Cookie: JSESSIONID=3D29D6099D55422892981E516391F158; Path=/; HttpOnly}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Cache-Control: no-cache, no-store, max-age=0, must-revalidate}{Pragma: no-cache}{Expires: 0}{X-Frame-Options: DENY}{WWW-Authenticate: Basic realm="Realm"}{Content-Length: 0}{Date: Mon, 25 Nov 2019 05:06:36 GMT}
2019-11-24 21:06:36.030 DEBUG 20980 --- [gistrationTask1] o.s.web.client.RestTemplate : Response 401 UNAUTHORIZED
2019-11-24 21:06:36.033 DEBUG 20980 --- [gistrationTask1] d.c.b.a.c.r.ApplicationRegistrator : Failed to register application as Application(name=spring-boot-application, managementUrl=http://ITS-ESG-T2-3025.ad.wsu.edu:8081/actuator, healthUrl=http://ITS-ESG-T2-3025.ad.wsu.edu:8081/actuator/health, serviceUrl=http://ITS-ESG-T2-3025.ad.wsu.edu:8081/) at spring-boot-admin ([http://localhost:8080/instances]): 401 null
If anyone could help provide me with some insight I'd greatly appreciate it.
This was caused by dependency conflicts that gradle wasn't able to successfully resolve. The fact that I was using spring boot 2.1.7 and boot admin was built on 2.1.5 there were libraries that were either deprecated in 2.1.7 or moved to a different package. Rolling back to 2.1.5 across the board resolved this.