I'd like to exclude the toggle-console from being included in the spring-security auth process: I want to access it on the management port without auth. Despite adding matchers to the requestMatchers in my WebSecurityConfig the console is always blocked by the login prompt.
The SecurityFilterChain bean I have:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(requests -> requests
.requestMatchers("/actuator",
"/actuator/*",
"/togglz-console",
"/togglz-console/**",
"/togglz*",
"/togglz**"
)
.permitAll()
.anyRequest()
.authenticated()
)
.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractAuthenticationFilterConfigurer::permitAll)
.logout(LogoutConfigurer::permitAll)
.build();
}
in application.properties I have the following:
togglz:
enabled:
true
features:
CHEEKY_GREETING:
enabled: false
console:
secured: false
use-management-port: true
endpoint:
enabled: true
id: togglz
management:
endpoints:
web:
exposure:
include: 'togglz, health'
server:
port: 8081
My project has the following dependencies:
plugins {
id 'org.springframework.boot' version '3.1.0'
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}
ext {
togglz_version = "4.0.1"
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation('org.springframework.boot:spring-boot-starter-test')
implementation("org.togglz:togglz-spring-boot-starter:${togglz_version}")
implementation("org.togglz:togglz-console:${togglz_version}")
}
I tried adding the togglz-security-spring-boot-starter
too, but made no change.
Code all on a branch here: https://github.com/robjwilkins/showcase/tree/add/togglz
Any suggestions what I'm doing wrong? thanks
The cause of this problem is that when the request for /togglz-console
is checked by PathPatternMatchableHandlerMapping
it looks at
ServletRequestPathUtils.getParsedRequestPath(request).pathWithinApplication()
The request path is /togglz-console
, however pathWithinApplication()
returns ""
. For some reason /togglz-console
is not being considered 'part of the application' (perhaps because it's being provided as a 3rd party add-on).
A solution to this is to add special requestMatcher
, which can be configured to look at the whole request path, and ignore the pathWithinApplication
.
for example:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(requests ->
requests
.requestMatchers(customMatcher("/togglz-console"),
customMatcher("/togglz-console/*"))
.permitAll()
.requestMatchers("/public")
.permitAll()
.anyRequest()
.authenticated()
.formLogin(withDefaults())
.build();
}
private RequestMatcher customMatcher(String pattern) {
return request -> {
var matcher = new PathPatternParser().parse(pattern);
var path = ServletRequestPathUtils.parseAndCache(request);
return matcher.matches(path);
};
}