Adding WebSecurityConfig causes a 404 error - spring

When I add in my websecurityconfig file, I get a 404 error. My Websecurityconfig looks like the following. What is annoying is this works locally but not when deployed. I try to hit the head of my application which I would expect to redirect to the login page but it 404's before logging in
package org.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.example.demo.LoginSuccessHandler;
import javax.sql.DataSource;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/abc").hasAnyAuthority("ROLE_one")
.antMatchers("/def").hasAnyAuthority("ROLE_one")
.antMatchers("/ghi").hasAnyAuthority("ROLE_one")
.antMatchers("/jkl").hasAnyAuthority("ROLE_one")
.antMatchers("/mno").hasAnyAuthority("ROLE_one")
.antMatchers("/pqr").hasAnyAuthority("ROLE_one")
.antMatchers("/stu").hasAnyAuthority("ROLE_two")
.antMatchers("/vwx").hasAnyAuthority( "ROLE_two")
.antMatchers("/yza").hasAnyAuthority("ROLE_two")
.antMatchers("/bcd").hasAnyAuthority("ROLE_two")
.antMatchers("/").permitAll()
.and().formLogin()
.successHandler(successHandler)
.and().logout().permitAll();
}
#Autowired private LoginSuccessHandler successHandler;
}
I have tried removing it which gets rid of the 404 error but I need the security to be set up.

A 404 means no page has been found for the url you are trying to access. You have the below setting for your HttpSecurity, meaning anyone can access the root of your application and it looks like no page or index.html is defined for it -
.antMatchers("/").permitAll()
Do you have a different package you deploy and locally you have the a page defined for root url which is why you do not see a 404?

turns out I did not have my application.properties file filled out correctly to connect with my database. fixing that fixed the error.
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=create
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/<application_name>
spring.datasource.username=<username>
spring.datasource.password=<password>
and I needed to use Controller and not RestController everywhere

Related

Why am I redirected directly to login page instead of index.html in Spring?

I am learning to design a login page in Spring Boot. I have not created any file named login, instead I have created an index page but by default it is redirecting me to login page?
package com.main.medipp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#SuppressWarnings("deprecation")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Bean
public UserDetailsService userDetailsService() {
return (UserDetailsService) new CustomUserDetailsService();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/sign_up").permitAll()
.antMatchers("/users").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.usernameParameter("email")
.defaultSuccessUrl("/users")
.permitAll()
.and()
.logout().logoutSuccessUrl("/").permitAll();
}
}
This is the code , i used , please help me with what changes should i make now!!
If you have secured your / endpoint, you will get redirected to the default login page. To fix that, add a rule to the / endpoint to disable authentication and redirect to the index page via a Controller.

UnsatisfiedDependencyException

need your help to optimize and solve my issue trying to implement oauth2.
I try to implement it on my backend, i received some code from to add in my project but i got an issue that i can't resolve even by looking over google.
First issue when compiling
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'authorizationServerConfiguration':
Unsatisfied dependency expressed through field
'authenticationManager'; nested exception is
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'securityConfiguration': Requested bean
is currently in creation: Is there an unresolvable circular reference?
Second issue when compiling
Caused by:
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'securityConfiguration': Requested bean
is currently in creation: Is there an unresolvable circular reference?
AuthorizationServerConfiguration.java
package com.kfm.management.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private TokenStore tokenStore;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("angular")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT", "USER")
.scopes("read", "write")
.autoApprove(true)
.secret(passwordEncoder.encode("angular-secret"));
}
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public PasswordEncoder passwordEncoder;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore);
endpoints.userDetailsService(userDetailsService);
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
//
}
SecurityConfiguration
package com.kfm.management.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.ArrayList;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public UserDetailsService customUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable()
.authorizeRequests().and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout() // Metodo get pues he desabilitado CSRF
.permitAll();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
ArrayList<String> allowed = new ArrayList<String>();
allowed.add("*");
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(allowed);
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
configuration.setAllowCredentials(false);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
I have to admit that i'm a bit lost with all that configuration steps!
Thks for your help!

Spring Basic Auth not working using BCrypt Encoding - I am getting redirected to login popup again even after entering correct credentials

Below is my PasswordEncoder Class
package com.example.springsecuritybasic.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
public class PasswordConfig {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Below is my ApplicationSecurityConfig Class
package com.example.springsecuritybasic.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
#Configuration
#EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter{
private final PasswordEncoder passwordEncoder;
#Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","index","/css/*","/js/*")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Override
protected UserDetailsService userDetailsService() {
UserDetails annasmithUser = User.builder()
.username("anna")
.password(passwordEncoder.encode("password"))
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
annasmithUser
);
}
}
Below is my Main Class -
package com.example.springsecuritybasic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringsecuritybasicApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecuritybasicApplication.class, args);
}
}
From the WebSecurityConfigurerAdapter#userDetailsService Javadoc:
Allows modifying and accessing the UserDetailsService from userDetailsServiceBean() without interacting with the ApplicationContext. Developers should override this method when changing the instance of userDetailsServiceBean().
To configure a custom user, you can register a UserDetailsService bean rather than overriding the method
#Bean
protected UserDetailsService userDetailsService() {
UserDetails annasmithUser = User.builder()
.username("anna")
.password(this.passwordEncoder.encode("password"))
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
annasmithUser
);
}

Spring Security work with Chrome but allow GET from Postman without authorization

i have problem with my spring security implemntation.
I have some basic configuration of UserDetails and UserDetailsService.I've done some Endpoints and some Security Configuration with WebSecurityConfigurerAdapter.
Everything works fine on chrome - if you try to access an secured endpoint security cofniugration redirects you to login form and after login redirects you to yours /api.
But in postman when sending even GET request authorization not working and you can fetch reposonse with all data that sould be availabe only for admin or after authorization.
Here is my Security Configuration
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableWebSecurity
#EnableTransactionManagement
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
AuthenticationSuccessHandler successHandler;
#Autowired
UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http./*sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
and().*/
authorizeRequests()
.antMatchers("/api/players").hasAnyRole("ADMIN")
.antMatchers("/api/organizers").hasAnyRole("ADMIN")
.antMatchers("/api/events").permitAll()
.antMatchers("/h2-console/**").permitAll()
.and()
.formLogin()
.successHandler(successHandler)
.permitAll()
.and()
.logout()
.permitAll()
/*.and()
.csrf().disable()*/;
}
#Bean
public PasswordEncoder getPasswordEncoder() {return NoOpPasswordEncoder.getInstance();}
}
and configuration for sample GET endpoint
#RestController
#RequestMapping(value="/api",produces = MediaType.APPLICATION_JSON_VALUE)
#RequiredArgsConstructor
public class UserViewRestContoller {
#NonNull
private final UserQuery query;
#GetMapping(value="/players")
#PreAuthorize("hasRole('ADMIN')")
List<PlayerView> getPlayers() {
return query.listPlayers();
}
#GetMapping(value="players/{userId}",produces = MediaType.APPLICATION_JSON_VALUE)
#PreAuthorize("#userId == authentication.principal.userId or hasRole('ADMIN')")
PlayerDetails getPlayer(#PathVariable UUID userId){
return query.getPlayerDetails(userId);
}
So in browser accesing /api/players you will see
and in POSTMAN
Did you enable global method security?
#EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
Also I don't see any JWT token implementation in the code. How are you getting admin role and authorize it. Where do you get Admin role?
I have found the problem, it was the definition of antMatchers:
.antMatchers("/api/players")
It only secures /api/players not /api/players/ and /api/players/**.
The proper ant matchers should be:
.antMatchers("/api/players/**").hasAnyRole("ADMIN")

Upgrading to spring-boot 1.4.1 - OAuth2 Security integration tests pass but client apps cannot log in

I have just upgraded an app from spring-boot 1.3.5 to spring-boot 1.4.1
For some reason, all my integration tests pass using oauth2. The test client can register users and perform operations with them during the maven integration test phase.
However when I start up my API server (which also contains the resource and authorization servers currently) clients can no longer get a bearer token.
My ClientDetailsService is never called on client login - but is registered with
#Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
on application startup.
Any ideas anyone?
Here is the relevant code:
Authorization Server Config:
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.api.security.ClientDetailsServiceImpl;
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Inject
private AuthenticationManager authenticationManager;
#Inject
private ClientDetailsServiceImpl clientDetailsService;
#Inject
private UserDetailsService userDetailsService;
public AuthorizationServerConfiguration() {
System.out.println("loaded");
}
// beans
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
// FIXME: Include a more secure key in the java token store
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
#Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
// config
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
endpoints.userDetailsService(userDetailsService);
}
#Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
Resource Server Config:
import javax.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.security_lib.config.UserDetailsServiceImpl;
#Configuration
#EnableResourceServer
#EnableWebSecurity
#ComponentScan("blablabla.api.security")
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Inject
private UserDetailsServiceImpl userDetailsService;
#Inject
private TokenStore tokenStore;
// Beans
#Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
// global security concerns
#Bean
public AuthenticationProvider authProvider() {
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
return authProvider;
}
#Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
#Primary
#Bean
public ResourceServerTokenServices getTokenServices () {
DefaultTokenServices services = new DefaultTokenServices();
services.setSupportRefreshToken(true);
services.setTokenStore(tokenStore);
return services;
}
// http security concerns
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();
/*http
.authorizeRequests().regexMatchers("^/members").anonymous()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();*/
}
}
A few things I've also noticed - this all might mean something to somebody.
When login does not work (starting up the api and using a client)
The org.springframework.security.web.access.expression.WebExpressionVoter is passed a Collection containing one attribute of type org.springframework.security.web.access.expression.WebExpressionConfigAttribute with the value of
"#oauth2.throwOnError(authenticated)"
When login does work (running an acceptance test)
The org.springframework.security.web.access.expression.WebExpressionVoter is passed a Collection containing one attribute of type org.springframework.security.web.access.expression.WebExpressionConfigAttribute with the value of
"[fullyAuthenticated]"
So this turned out to not be a spring-boot issue at all, but instead some kind of issue that was caused in our gateway server when upgrading from spring-cloud Brixton.M2 release train to Brixton.RELEASE. This is sort of an unhelpful answer to an unhelpful question, so - happy to see this removed from SO.

Resources