поэтому я настраивал безопасность для своего API, где вы должны войти в систему с именем пользователя / паролем, получить токен JWT, а затем использовать его для всего остального. Вот как я настроил SecurityWebFilterChain:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/login", "/")
.permitAll()
.and()
.addFilterAt(UsernamePasswordAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange()
.pathMatchers("/api/**")
.authenticated()
.and()
.addFilterAt(bearerAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION);
return http.build();
}
, как вы можете видеть здесь, я установил два пользовательских фильтра. Один для имени пользователя / пароля и другой для токена на предъявителя (JWT).
Вот так я настраиваю фильтр UsernamePassword, где я предоставляю своему настраиваемому authManager пользовательскую службу UserDetails, кодировщик и обработчик успеха:
private AuthenticationWebFilter UsernamePasswordAuthenticationFilter() {
UserDetailsRepositoryReactiveAuthenticationManager authManager;
AuthenticationWebFilter usernamePasswordAuthenticationFilter;
ServerAuthenticationSuccessHandler successHandler;
authManager = new UserDetailsRepositoryReactiveAuthenticationManager(applicationUserService);
authManager.setPasswordEncoder(passwordEncoder);
successHandler = new AuthenticationSuccessHandler();
usernamePasswordAuthenticationFilter = new AuthenticationWebFilter(authManager);
usernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(successHandler);
return usernamePasswordAuthenticationFilter;
}
Это на самом деле работает, я могу отправить запрос GET с помощью curl или Postman следующим образом:
curl -v -u username:password localhost:8080/login
и получить свой токен JWT обратно. классно. Всего одна проблема. По умолчанию этот фильтр использует
ServerHttpBasicAuthenticationConverter
Что я на самом деле хочу: Мне нужно отправить запрос POST с именем пользователя и паролем в теле запроса в простой JSON структуре вот так:
{
"username":"usr"
"password":"pass"
}
и используйте его для создания объекта аутентификации.
Это то, что я пробовал: Я создал и добавил пользовательский Преобразователь в мой AuthenticationFilter:
usernamePasswordAuthenticationFilter.setServerAuthenticationConverter(new UsernamePasswordAuthenticationConverter());
UsernamePasswordAuthenticationConverter:
public class UsernamePasswordAuthenticationConverter implements ServerAuthenticationConverter {
@Override
public Mono<Authentication> convert(ServerWebExchange exchange) {
...
}
}
Здесь я застрял на несколько часов.
Question1 Как мне получить имя пользователя / пароль из JSON тела запроса и выдать Mono<Authentication>
здесь? Я довольно новичок в реактивном программировании, извините, если это глупый вопрос.
Question2 Только GET-запросы, кажется, даже достигают этого пользовательского UsernamePasswordAuthenticationConverter. Почему? любые запросы POST отклоняются до этого, и я не понимаю, почему.