O Я настраивал безопасность для реактивного API, когда пользователи могут войти в систему с именем пользователя / паролем, чтобы получить токен JWT, а затем использовать его для всего остального. Данные пользователя (имя пользователя, пароль и т. Д. c, др. c) хранятся в MongoDb.
Я просто добавляю фильтр в цепочку веб-фильтров:
.addFilterAt(buildUsernamePasswordAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
При создании этого фильтра я даю ему свой собственный ApplicationUserService
:
private AuthenticationWebFilter buildUsernamePasswordAuthenticationFilter() {
UserDetailsRepositoryReactiveAuthenticationManager authManager;
AuthenticationWebFilter usernamePasswordAuthenticationFilter;
authManager = new UserDetailsRepositoryReactiveAuthenticationManager(applicationUserService);
authManager.setPasswordEncoder(passwordEncoder);
usernamePasswordAuthenticationFilter = new AuthenticationWebFilter(authManager);
usernamePasswordAuthenticationFilter.setRequiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers(loginPathMatcher));
return usernamePasswordAuthenticationFilter;
}
Вот как выглядит ApplicationUserService
:
@Service
public class ApplicationUserService implements ReactiveUserDetailsService {
private final ReactiveUsersService reactiveUsersService;
@Autowired
public ApplicationUserService(ReactiveUsersService reactiveUsersService) {
this.reactiveUsersService = reactiveUsersService;
}
@Override
public Mono<UserDetails> findByUsername(String username) {
return reactiveUsersService.getUserByUsername(username).cast(UserDetails.class).log();
}
}
Здесь используется ReactiveUsersService
для выборки пользователей:
@Service
public class ReactiveUsersService {
ReactiveUsersRepository repository;
public ReactiveUsersService(ReactiveUsersRepository repository) {
this.repository = repository;
}
public Flux<User> getUsers(){
return repository.findAll().switchIfEmpty(Mono.error(new IllegalStateException("no users"))
);
}
public Mono<User> getUserByUsername(String username){
return repository.findByUsername(username);
}
}
И, наконец, ReactiveUsersRepository
:
@Repository
public interface ReactiveUsersRepository extends ReactiveMongoRepository<User, Integer> {
Mono<User> findByUsername(String username);
}
При такой настройке я не получаю ошибок, но войти в систему не получается. Я просто получаю 401 обратно . Обратите внимание: я добавил .log()
туда, куда я беру пользователя. Вот что он регистрирует:
2020-05-06 17:23:54.741 INFO 23348 --- [ctor-http-nio-3] reactor.Mono.MapFuseable.1 : | onSubscribe([Fuseable] FluxMapFuseable.MapFuseableSubscriber)
2020-05-06 17:23:54.742 INFO 23348 --- [ctor-http-nio-3] reactor.Mono.MapFuseable.1 : | request(unbounded)
2020-05-06 17:23:54.743 INFO 23348 --- [ctor-http-nio-3] reactor.Mono.MapFuseable.1 : | onContextUpdate(Context2{interface org.springframework.web.server.ServerWebExchange=org.springframework.web.server.adapter.DefaultServerWebExchange@750265e1, interface org.springframework.security.core.context.SecurityContext=MonoFlatMap})
2020-05-06 17:23:54.743 INFO 23348 --- [ctor-http-nio-3] reactor.Mono.MapFuseable.1 : | onContextUpdate(Context2{interface org.springframework.web.server.ServerWebExchange=org.springframework.web.server.adapter.DefaultServerWebExchange@750265e1, interface org.springframework.security.core.context.SecurityContext=MonoFlatMap})
2020-05-06 17:23:54.744 INFO 23348 --- [ctor-http-nio-3] reactor.Mono.MapFuseable.1 : | onContextUpdate(Context2{interface org.springframework.web.server.ServerWebExchange=org.springframework.web.server.adapter.DefaultServerWebExchange@750265e1, interface org.springframework.security.core.context.SecurityContext=MonoFlatMap})
2020-05-06 17:23:54.825 INFO 23348 --- [ntLoopGroup-2-2] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:104}] to localhost:27017
2020-05-06 17:23:54.844 INFO 23348 --- [ntLoopGroup-2-2] reactor.Mono.MapFuseable.1 : | onNext(User{id='5eb10474d388c2b64f709b4c', username='admin', email='admin@admin.com', password='$2a$10$qj83J33wn7l9IpNvAlAFQ.fDxaQGwl5Pw4nHRho.Y2wWs1goJny5e', roles=null})
2020-05-06 17:23:54.854 INFO 23348 --- [ntLoopGroup-2-2] reactor.Mono.MapFuseable.1 : | cancel()
2020-05-06 17:23:54.854 INFO 23348 --- [ntLoopGroup-2-2] reactor.Mono.MapFuseable.1 : | onContextUpdate(Context2{interface org.springframework.web.server.ServerWebExchange=org.springframework.web.server.adapter.DefaultServerWebExchange@750265e1, interface org.springframework.security.core.context.SecurityContext=MonoFlatMap})
2020-05-06 17:23:54.855 INFO 23348 --- [ntLoopGroup-2-2] reactor.Mono.MapFuseable.1 : | onComplete()
Раньше я подключал MongoDb к ApplicationUserService
. Я использовал InMemoryUsersService
, где у меня было несколько жестко заданных пользователей вместо ReactiveUsersSercvce, и все работало нормально. По сути, я просто изменил эту строку, чтобы получить пользователей из Mon go вместо памяти:
return reactiveUsersService.getUserByUsername(username).cast(UserDetails.class).log();
Кажется, что он DID получил пользователя из Mon go, но не смог его аутентифицировать. Это не дает мне никаких ошибок или чего-то еще, и я новичок в этой реактивной пружине. Я изо всех сил пытаюсь отладить это и получить что-нибудь для gr asp.