I have a React Client App where I am using msal-react to authenticate the user and generate an access token (API: /oauth2/v2.0/token) along with a bunch of other details like refresh_token, id, scope, etc.
I want to just use the access token and pass in the authorization header to my backend application which is a WebFlux application using Spring Security 5 and SpringBoot 3. The backend should validate the bearer token by hitting the MS endpoint (https://graph.microsoft.com/v1/me). Exception is the request to be authorized if it returns a valid user for the token.
But the SecurityWebFilterChain I am configuring is not working as expected.
Suppose I am trying to fetch this API:
@GetMapping("/secure-api")
public Mono<String> getSecureResponse() {
return Mono.just("Secure Response");
}
Following is my Security Configuration:
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
private final ReactiveAuthenticationManager authenticationManager;
public SecurityConfig(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Bean
public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
return http.authorizeExchange().anyExchange().authenticated().and()
.authenticationManager(authenticationManager).build();
}
}
AuthenticationManager:
@Bean
ReactiveAuthenticationManager customAuthenticationManager() {
return authentication -> Mono.just(customAuthentication(authentication));
}
private Authentication customAuthentication(Authentication authentication) {
String token = authentication.getCredentials().toString();
MsAuthResponse authResponse = this.authenticateService.callMicrosoftGraphMeEndpoint(token);
if (authResponse == null) {
throw new BadCredentialsException("Authentication failure for token = " + token);
}
return new UsernamePasswordAuthenticationToken(authResponse, token, Collections.emptyList());
}
callMicrosoftGraphMeEndpoint() is a simple rest call which will validate the token and return User details returned by MS.
I tried a few other things along with this but none seem to work for me it seems. When I put a breakpoint inside the authenticationManager code, it never gets hit.