簡體   English   中英

@AuthenticationPrincipal UserModel 用戶始終為 Null。 我嘗試了很多解決方法

[英]@AuthenticationPrincipal UserModel user is always Null. I tried many solution methods

有一個 controller 的任務是使用 REST API 將用戶配置文件返回給我。 進一步編碼:

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

我為用戶實體創建了一個 model。 實體 class 創建為:

public class User implements UserDetails { ... }

model結構如下:

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
}

在 model 中,我將(或到目前為止計划)從 AuthPrincipal 中提取授權用戶的數據。 根據工作說明,我不能使用默認的Principal,我什至沒有嘗試過。 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 和這個堆棧上 - 沒有:(

如果我應該添加更多信息,請寫評論。


更新 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. 確保您使用的是org.springframework.security.core.annotation.AuthenticationPrincipal而不是@org.springframework.security.web.bind.annotation.AuthenticationPrincipal (兩者都應該有效,但只是預先注意,因為后者已被棄用)

  2. 現在的問題是將問題隔離到以下區域之一,以便您可以集中精力:

    1. 您的UserDetailsServiceImpl未使用
    2. 使用@AuthenticationPrincipalgetUserProfile方法有問題
    3. 用戶未與登錄的 session 關聯。
  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());
    }
  1. 檢查日志,它會告訴您問題出在哪里,如果您無法從中找出問題,您可以在此處發布結果以獲得更多幫助

更新:第 4 點的答案在評論中給出如下。

  • 主體:匿名用戶
  • 實現 UserDetails 的 class:class java.lang.String
  • 實現UserDetailsService的class:class
  1. 結論:端點不受保護,用戶無需登錄即可訪問

  2. 解決方案:通過將.antMatchers("/u/**").authenticated()替換為.antMatchers("/api/u/**").authenticated()來保護端點

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM