Как получить доступ к утверждениям JWT в методах-обработчиках Spring API с помощью Webflux? - PullRequest
3 голосов
/ 25 мая 2019

Я добавляю WebFilter для выполнения аутентификации JWT внутри SecurityWebFilterChain. Мы кодируем много информации, не связанной с аутентификацией, в JWT, которая необходима многим нашим конечным точкам API, поэтому мне нужно иметь возможность извлекать информацию из JWT и получать доступ к этой информации в моих методах-обработчиках API (например, LoginController). Джава). Каков наилучший шаблон для достижения этой цели?

Вот моя SecurityWebFilterChain, показывающая аутентификацию WebFilter:

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {

        return http
                .authorizeExchange()
                .pathMatchers("/login", "/")
                .authenticated()
                .and()
                .addFilterAt(basicAuthenticationFilter(), SecurityWebFiltersOrder.HTTP_BASIC)
                .authorizeExchange()
                .pathMatchers("/adm")
                .authenticated()
                .and()
                .addFilterAt(basicAuthenticationFilter(), SecurityWebFiltersOrder.HTTP_BASIC)
                .authorizeExchange()
                .pathMatchers("/api/**")
                .access(authorizationManager)
                .and()
                .addFilterAt(bearerAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
                .build();
    }

Здесь я хотел бы получить доступ к претензиям в LoginController.java:

.
@RestController()
@RequestMapping(value = "/login")
public class LoginController {

    private final UserMongoRepository repository;

    @Autowired
    public LoginController(UserMongoRepository repository) {
        this.repository = repository;
    }

    @PostMapping("")
    public Mono<User> login(@RequestBody User post,
                            @RequestParam String user_id,
                            @RequestParam String username) {

        //Need to access information from JWT claims here

        return this.repository.findById(user_id);
    }
}

1 Ответ

1 голос
/ 25 мая 2019

Я бы создал настроенный объект Authentication и сохранил бы необходимую информацию внутри него.

Для пользовательских данных храните их Principal. Для данных, не связанных с пользователем, звучит как Details. Это хорошее место для хранения.

Многие встроенные AuthenticationProvider создадут UserDetails и сохранят в Principal. Это означает, что вы можете просто создать таможенную UserDetails, если вы используете встроенную AuthenticationProvider.

Таким образом, в зависимости от того, как вы реализуете логику аутентификации, вам необходимо настроить соответствующие AuthenticationProvider или Filter и т. Д. Цель - получить доступ к HttpServletRequest, получить JWT из заголовка HTTP, проанализировать JWT, настроить и настройте этот настроенный объект Authentication и установите для него SecurityContext:

SecurityContextHolder.getContext().setAuthentication(authenication);

Для доступа к этому Authentication объекту в контроллере вы можете использовать:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
CurrentUser user = (CurrentUser) auth.getPrincipal();
CurrentRequestDetail detail= (CurrentRequestDetail) auth.getDetails();
/** CurrentUser and CurrentRequestDetail is the customised Principal and Details**/

Если вам нужен доступ только к [Principal], вы можете использовать @AuthenticationPrincipal:

    @PostMapping("")
    public Mono<User> login(@RequestBody User post,
                            @RequestParam String user_id,
                            @RequestParam String username,
                            @AuthenticationPrincipal CurrentUser currentUser) {

        //Need to access information from JWT claims here

        return this.repository.findById(user_id);
    }
...