I have Spring security config where I create AuthenticationWebFilter
for specific endpoint. In my case lets say its /api/login
. For this endpoint I want to authenticate user with Basic usr/pass authentication. Any other endpoint should be freely availbale with no auth.
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.csrf()
.disable()
.authorizeExchange()
.and()
.addFilterAt(buildUsernamePasswordAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange()
.anyExchange()
.permitAll();
return http.build();
}
private AuthenticationWebFilter buildUsernamePasswordAuthenticationFilter() {
UserDetailsRepositoryReactiveAuthenticationManager authManager = new UserDetailsRepositoryReactiveAuthenticationManager(applicationUserService);
authManager.setPasswordEncoder(passwordEncoder);
AuthenticationWebFilter usernamePasswordAuthenticationFilter = new AuthenticationWebFilter(authManager);
usernamePasswordAuthenticationFilter.setRequiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers("api/login"));
return usernamePasswordAuthenticationFilter;
}
I also have LoginController to handle login with AuthenticatedPinciple
:
@RestController
@RequestMapping("/api")
public class LoginController {
@PostMapping("/login")
public Mono<Map<String, Object>> login(@AuthenticationPrincipal Mono<AuthenticatedUser> user) {
....
}
}
Log-in with correct or incorrect credentials work fine as long as Authorization
header is present and valid.
The problem:
If I try to POST to this endpoint with corrupted or no Authorization
header at all, I want to send back 400 BAD_REQUEST, with preferably custom body, saying 'Invalid auth token' or w/e. I thought Springs AuthenticationWebFilter would take care of that. I was worng, instead it simply propagates null as AuthenticationPrinciple to LoginController where it crashes with 500 error. Not even an empty mono, but a null.
Question: What would be the best way to ensure proper Authorization
header is present when request is sent to '/api/login', and if not send back proper 400 response and not execute Controller mapping.
The best proper way is to use the built in basic authentication functionality in spring security. You dont need to create your own filter, httpBasic
is already available in spring security.
if you wish to apply security to only certain endpoints you can define this using antMatchers
.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.antMatchers("/api/login")
.authenticated()
)
.httpBasic(withDefaults());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.