Используйте @AuthenticationPrincipal с JwtAuthenticationToken, чтобы использовать собственный класс пользователя - PullRequest
0 голосов
/ 17 марта 2020

Я использую Spring Boot 2.2.5 с Spring Security 5.2.2 с использованием spring-security-oauth2-resource-server и spring-security-oauth2-jose зависимостей.

В моих методах контроллера у меня это работает:

@GetMapping
public ResponseEntity<?> doSomething(@AuthenticationPrincipal JwtAuthenticationToken principal) {
    User user = getUser(principal);
    ...
}

principal вводится и содержит идентификатор пользователя на Azure (я использую Azure AD B2 C).

Первое, что мне нужно сделать в каждом методе, это получить мой собственный User объект, используя этот приватный метод, который извлекает User из моего userService Spring bean-компонента:

    private User getUser(JwtAuthenticationToken principal) {
        AuthorizationServerUserId authorizationServerUserId = AuthorizationServerUserId.fromPrincipal(principal);
        return userService.findByAuthorizationServerUserId(authorizationServerUserId)
                          .orElseThrow(() -> UserNotFoundException.forAuthorizationServerUserId(authorizationServerUserId));
    }

Как настроить Spring (Boot) так, чтобы это работало:

@GetMapping
public ResponseEntity<?> doSomething(@AuthenticationPrincipal User user) {

}

В настоящее время настройка безопасности выполняется следующим образом:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .authorizeRequests(registry -> {
                    registry.antMatchers("/registration/**").permitAll();

                    registry.antMatchers("/api/**").authenticated();
                });
    }
}

1 Ответ

0 голосов
/ 17 марта 2020

@AuthenticationPrincipal принимает выражение SpEL в качестве параметра.

В указанном выражении SpEL можно указать компонент и метод, преобразующий принципала в User.

@GetMapping
public ResponseEntity<?> doSomething(@AuthenticationPrincipal(expression = "@userService.getUser(#this)") User user) {

}

где userService относится к компоненту UserService.

Вы можете сделать еще один шаг вперед, создав собственную аннотацию, которая использует @AuthenticationPrincipal в качестве мета-аннотации.

@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal(expression = "@userService.getUser(#this)")
public @interface CurrentUser {}

Тогда ваш контроллер станет

@GetMapping
public ResponseEntity<?> doSomething(@CurrentUser User user) {

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...