简体   繁体   中英

Spring Security how to ensure headers

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.

http 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM