[英]Error: User doesn't exist with this username: when using spring security
I'm building backend using Spring Boot + Spring Security and testing it with Postman.我正在使用 Spring Boot + Spring Security 构建后端并使用 Postman 对其进行测试。 For frontend I will use Android app.
对于前端,我将使用 Android 应用程序。
Implemented http basic auth
.实现了
http basic auth
。
When I click on the Authentication tab in Postman and choose Basic Auth from the drop down box and then I enter username and password fields there it works just fine.当我单击 Postman 中的“身份验证”选项卡并从下拉框中选择“基本身份验证”,然后在那里输入用户名和密码字段时,它工作得很好。 But when I am sending raw JSON request body I am getting following error:
但是当我发送原始 JSON 请求正文时,我收到以下错误:
org.springframework.security.authentication.InternalAuthenticationServiceException: User doesn't exist with this username:
I assume it is caused with this class我认为它是由这个类引起的
CustomUserDetailsService.java自定义用户详细信息服务.java
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
CustomUserDetails userDetails = null;
if(user != null){
userDetails = new CustomUserDetails();
userDetails.setUser(user);
}else{
throw new UserNotFoundException("User doesn't exist with this username: " + username);
}
return userDetails;
}
}
But I am not sure why as it works with Postman auth drop down box.但我不确定为什么它适用于 Postman auth 下拉框。
Here is more code that I use:这是我使用的更多代码:
SecurityConfiguration.java安全配置文件
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(encodePWD());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.csrf().disable();
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/rest/**").permitAll()
.and()
.authorizeRequests()
.antMatchers("/secure/**").hasAnyRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll();
}
@Bean
public BCryptPasswordEncoder encodePWD() {
return new BCryptPasswordEncoder();
}
}
CustomUserDetailsService.java自定义用户详细信息服务.java
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
CustomUserDetails userDetails = null;
if(user != null){
userDetails = new CustomUserDetails();
userDetails.setUser(user);
}else{
throw new UserNotFoundException("User doesn't exist with this username: " + username);
}
return userDetails;
}
}
CustomUserDetails.java自定义用户详细信息.java
@Getter
@Setter
public class CustomUserDetails implements UserDetails {
private User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role.getRole())).collect(Collectors.toSet());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Also I am using this to login user and to check if matches one in DB.我也用它来登录用户并检查是否匹配数据库中的一个。
@PostMapping("/loginuser")
ResponseEntity<Object> login(@RequestBody User user) {
List<User> userList = userRepository.findByUsernameAndPassword(user.getUsername(), user.getPassword());
if (userList.size() != 1) {
throw new UserNotFoundException("Entity not found");
} else {
return new ResponseEntity<>(userList.get(0), HttpStatus.OK);
}
}
Is it even possible to use https basic auth
for rest server api?甚至可以将
https basic auth
用于休息服务器 api 吗?
Or do I have to use some authentications with tokens like OAuth and similar?或者我是否必须使用一些带有 OAuth 等令牌的身份验证?
UPDATE更新
If you use the Postman Authorization tab, Postman constructs the corresponding Authorization header Authorization: Basic <credentials>
, where credentials
is the Base64 encoding of username and password.如果使用 Postman Authorization 选项卡,Postman 会构造相应的 Authorization 标头
Authorization: Basic <credentials>
,其中credentials
是用户名和密码的 Base64 编码。
You can see this header in your Postman request clicking headers and hidden.您可以在 Postman 请求中看到此标头,单击标头和隐藏。
This header is needed for Spring Security HTTP basic authentication. Spring Security HTTP 基本身份验证需要此标头。 If you just post username and password in the body of the request as JSON, Spring Security HTTP basic authentication cannot extract the username from the header.
如果您只是将用户名和密码作为 JSON 发布在请求正文中,则 Spring Security HTTP 基本身份验证无法从标头中提取用户名。 Therefore,
user
equals null
and the exception is thrown.因此,
user
等于null
并抛出异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.