Пользователь @AuthenticationPrincipal UserModel всегда имеет значение Null. Пробовал много способов решения - PullRequest
1 голос
/ 20 июня 2020

Есть контроллер, задача которого - вернуть мне профиль пользователя с помощью REST API. Код далее:

@PostMapping("/me")
public UserProfileResponse getUserProfile(@AuthenticationPrincipal UserAuthenticationPrincipalModel user ) {
    return userProfileService.getUserProfile(user.getUserId());
}

Я создал модель для сущности User. Класс сущности создается как:

public class User implements UserDetails { ... }

Модель имеет следующую структуру:

public class UserAuthenticationPrincipalModel extends User {
    private String userId;
    private String avatarUrl;

    public UserAuthenticationPrincipalModel(***.********.entity.User user) {
        super(user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(),
                user.isCredentialsNonExpired(), user.isAccountNonLocked(), user.getAuthorities());
        this.userId = user.getUserId();
        this.avatarUrl = user.getUserPic();
    }
// + equals and hashCode
}

В модели данные, которые я когда-либо (или пока планирую) вытащить из AuthPrincipal авторизованного пользователя. Согласно техническому заданию, я не могу использовать Принципала по умолчанию, даже не пробовал. Реализация UserDetailsService:

@Service
public class UserDetailsServiceImpl extends AbstractMySQLService<User, String, UserRepository> implements UserDetailsService {
    private final UserRepository userRepository;

    public UserDetailsServiceImpl(final UserRepository userRepository, final UserRepository repository) {
        super(repository);
        this.userRepository = userRepository;
    }

    @Override
    public UserAuthenticationPrincipalModel loadUserByUsername(final String email) {
        User user = userRepository.findByEmail(email);

        if (user == null) {
            throw new UsernameNotFoundException("Invalid username or user not e: " + email);
        }

        return new UserAuthenticationPrincipalModel(user);
    }
}

Ошибка: Null всегда слетает в методы. Внесено много дополнений, которые рекомендуются для Baeldang и этого стека - ничего: (

Напишите, пожалуйста, комментарий, если нужно добавить дополнительную информацию.

UPD 1:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/ca/**").hasRole("COMPANY_ADMIN")
                .antMatchers("/d/**").hasRole("DRIVER")
                .antMatchers("/u/**").authenticated()
                .antMatchers("/sign_up", "/oauth/token", "/swagger-ui.html", "/resources").permitAll();
    }

1 Ответ

1 голос
/ 20 июня 2020

Я могу дать вам несколько советов о том, как подойти к этой проблеме.

  1. Убедитесь, что вы используете org.springframework.security.core.annotation.AuthenticationPrincipal вместо @org.springframework.security.web.bind.annotation.AuthenticationPrincipal (оба должны работать, но только с осторожностью потому что более поздняя версия устарела)

  2. Теперь проблема состоит в том, чтобы изолировать проблему от ONE из следующих областей, чтобы вы могли сосредоточиться на них:

    1. Ваш UserDetailsServiceImpl не используется
    2. Что-то не так с методом getUserProfile с @AuthenticationPrincipal
    3. пользователь не связан с вошедшим в систему сеансом.
  3. Чтобы определить это, замените свой метод public UserProfileResponse getUserProfile следующим: [Больше ничего не менять]

    @Autowired
    private UserDetailsService userDetailsService;

    @PostMapping("/me")
    public void getUserProfile(@AuthenticationPrincipal UserDetails user ) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        System.out.println("principal : " + authentication.getPrincipal());
        System.out.println("Implementing class of UserDetails: " + authentication.getPrincipal().getClass());
        System.out.println("Implementing class of UserDetailsService: " + userDetailsService.getClass());
    }
Проверьте журналы, и он скажет вам, в чем проблема, и если вы не можете понять из этого, вы можете опубликовать результат здесь для получения дополнительной помощи

Обновление: Ответы на пункт 4, указанные ниже в комментариях.

  • принципал: anonymousUser
  • Реализация класса UserDetails: class java .lang.String
  • Реализация класса UserDetailsService: class

Заключение: конечная точка не защищена и пользователь получает доступ без входа в систему

Решение: Защитите конечную точку, заменив .antMatchers("/u/**").authenticated() на .antMatchers("/api/u/**").authenticated()

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