簡體   English   中英

當發送登錄請求時,@AuthenticationPrincipal 的用戶為空

[英]When send login request user be null for @AuthenticationPrincipal

當我嘗試從前端登錄時,出現錯誤。 我可以注冊,但我無法登錄。

錯誤

java.lang.NullPointerException:無法調用“com.app.auction.user.User.getName()”,因為“user”在 com.app.auction.user.UserVM.(UserVM.java:17) 處為空 ~[類/:na] 在 com.app.auction.auth.AuthController.handleAuthentication(AuthController.java:21) ~[classes/:na]

我嘗試向這個 api 發送請求。

授權控制器

@RestController
public class AuthController {
    
    @Autowired
    UserRepository userRepository;

    @PostMapping("/auth")
    UserVM handleAuthentication(@CurrentUser User user) {
        return new UserVM(user);
    }
}

@當前用戶

@Target({ElementType.PARAMETER})/
@Retention(RetentionPolicy.RUNTIME)
@AuthenticationPrincipal  
public @interface CurrentUser {

}

用戶虛擬機

package com.app.auction.user;

import lombok.Data;

@Data
public class UserVM {
    
    private String name;
    
    private String username;
    
    private String email;
    
    private String image;
    
    public UserVM(User user) {
        this.name = user.getName();
        this.email = user.getEmail();
        this.username=user.getUsername();
        this.image=user.getImage();
    }
}

無角色用戶

@Data
public class UserWithoutRole {
    
    @NotNull(message="Name can not be null")
    @Size(min = 2, max=50, message = "Name must be more than 2 letters ")
    private String name;
    

    @NotNull(message="Username can not be null")
    @UniqueUsername
    @Size(min=1,max=100  )
    private String username;
    
    @NotNull(message="Email can not be null")
    private String email;
    
    
    @NotNull(message="Password can not be null")
    @Size(min = 4, max=16 , message = "Password must be a minimum of 4 characters and a maximum of 16 characters. ")
    private String password;

    private String image;
    
}

用戶

@Data
@Entity
public class User  implements UserDetails{
    
    

    /**
     * 
     */
    private static final long serialVersionUID = -2725432351214985546L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id;
    
    private String name;
    

    private String username;
    
    private String email;
    
    
    private String password;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "users_roles", 
    joinColumns = @JoinColumn(name = "user_id"), 
    inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Collection<Role> roles;
    
    
    private String image;

    public User() {
        
    }
    public User(UserWithoutRole user) {
        this.name = user.getName();
        this.email = user.getEmail();
        this.username=user.getUsername();
        this.image=user.getImage();
    }
    
    

   @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<Role> roles = getRoles();
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
         
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
         
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }


    
}

安全配置

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    @Autowired
    UserAuthService userAuthService;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.httpBasic(); 
        
        http.httpBasic().authenticationEntryPoint(new AuthEntryPoint());

        http.authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers(HttpMethod.POST,"/auth").authenticated()
            .and()
            .authorizeRequests().anyRequest().permitAll();
        
        
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userAuthService).passwordEncoder(passwordEncoder());
    }
    

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

用戶詳情服務

@Service
public class UserAuthService implements UserDetailsService{

@Autowired
UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username); //my user implements UserDetails it can return
     if(user != null && user.isEnabled()){
        return buildUserForAuthentication(user, mapRolesToAuthorities(user.getRoles()));
    }else {
        throw new UsernameNotFoundException("User not found");
    }
}

private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles) {
    return roles.stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
}

UserDetails buildUserForAuthentication(User user, Collection<? extends GrantedAuthority> collection) {
      return new org.springframework.security.core.userdetails.User(user.getUsername(),
        user.getPassword(), collection);
}

}

我解決了問題。 即使用戶實現了 UserDetails,我也無法獲得 @CurrentUser。 我將身份驗證作為參數獲取,然后轉換為我的 User 類。

@PostMapping("/auth")
UserVM handleAuthentication(Authentication authentication) {//@CurrentUser User user
    User user=userService.getByUsername(authentication.getName());
    return new UserVM(user);
}

暫無
暫無

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

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