当前位置: 首页 > 知识库问答 >
问题:

发送登录请求时,@AuthenticationPrincipal的用户为null

太叔英卫
2023-03-14

当我尝试从前端登录时,我遇到了一个错误。我可以注册,但我不能登录。

错误:

Java语言lang.NullPointerException:无法调用“com.app.auction.user.user.getName()”,因为“user”在com上为null。应用程序。拍卖使用者UserVM。(UserVM.java:17)~(classes/:na)位于com。应用程序。拍卖授权。AuthController。handleAuthentication(AuthController.java:21)~[类/:na]

我尝试向此api发送请求。

AuthController

@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;
    }


    
}

安全配置(SecurityConfiguration)

@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);
}

}

共有1个答案

农雅畅
2023-03-14

我解决了问题。即使User实现了User详细信息,我也无法获取@MONtUser。我将身份验证作为参数并转换为我的User类。

@PostMapping("/auth")
UserVM handleAuthentication(Authentication authentication) {//@CurrentUser User user
    User user=userService.getByUsername(authentication.getName());
    return new UserVM(user);
}
 类似资料:
  • 我试图弄清楚如何使用IdP发起的请求和Sustainsys SAML2库在标准Web Forms应用程序中登录用户和Owin启用的Web Forms应用程序。 我在Azure上有IdP,我可以发送请求,Azure可以将带有SAMLResponse的POST发送到我的ACSendpoint。 但我不知道如何使用此令牌登录用户。Sustainsys文档中没有示例。 On Azure IdP Basic

  • 我想向soap请求发送XML,我使用python请求,如下所示: 当我发送请求时,我会发出以下请求: 我在这样的请求中进行: 我给出了一些错误,比如你不能发送这样的请求。 我意识到我必须发送带有此请求的证书才能获得成功响应 我有<代码>。cer和。crt文件发送,但我这样发送: 并得到以下错误: 更新: 我在PK中使用openssl x509-inform der。cer-输出PK。pem并尝试以

  • 发送请求 发送同步请求 Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send(); String clientVersion = web3Client

  • 我有这个代码: 我一直在犯这样的错误: java:不兼容的类型:com。应用句子分类请求。无法将生成器转换为com。应用句子分类请求 我已经使用Maven插件生成了gRPC Java文件。在看了多个例子后,我不确定我的问题是什么。

  • 问题内容: 我正在尝试找到一种无需使用Python即可通过浏览器自动登录Facebook的方法。我尝试了“请求”库。尝试了几种方法: … … 最后一种方法填充页面上的“电子邮件”框,但“通过”框保持为空… 有人可以帮我吗?是否可以使用请求模拟FB登录? 谢谢! 问题答案: 您需要发送完整的表格。找出Facebook期望的最简单方法是使用类似Google Chrome的开发人员工具的工具 来监视您的

  • 问题内容: 在我的Django应用中,我需要在用户登录时开始运行一些定期的后台作业,并在用户注销时停止运行它们,因此我正在寻找一种优雅的方式 收到用户登录/注销的通知 查询用户登录状态 在我看来,理想的解决方案是 由每个发送的信号和 一种类似于… 或… Django 1.1.1没有该功能,我不愿意修补该源代码并添加它(无论如何都不确定如何做到)。 作为一个临时解决方案,我向UserProfile模