Spring 启动 UserNotFound 消息
Spring boot UserNotFound message
我正在尝试在 spring 引导 (2.5.3) 中进行基本身份验证,并在数据库中找不到用户时调用 UserNotFoundException。
@Override
public User findByUserName(String username){
try {
return (User) template.queryForObject("SELECT * FROM USERS WHERE email = ?",
new BeanPropertyRowMapper(User.class), username);
} catch (EmptyResultDataAccessException e) {
throw new UsernameNotFoundException("User not found");
}
}
但结果我收到消息“Bad Credential”。 BadCredential Exception 改变了我的异常。
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException ex) throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
//HttpStatus.FORBIDDEN
Map<String, Object> data = new HashMap<>();
data.put(
"timestamp",
Calendar.getInstance().getTime());
data.put(
"exception",
ex.getMessage());
System.out.println(ex.getClass());
response.getOutputStream()
.println(objectMapper.writeValueAsString(data));
}
class org.springframework.security.authentication.BadCredentialsException
我应该覆盖什么才能看到 UserNotFoundException 错误消息?
创建自定义 Auth 提供程序
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private Repository repository;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
User user = repository.findByUserName(name);
if(!encoder().matches(password, user.getPassword())){
throw new BadCredentialsException("Bad credentials");
}
return new UsernamePasswordAuthenticationToken(user, password,
Arrays.asList(new SimpleGrantedAuthority("USER_ROLE")));
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
就像那里解释的那样https://www.baeldung.com/spring-security-authentication-provider
您可以将 AuthenticationProvider
配置为在找不到用户名时抛出 UsernameNotFoundException
而不是 BadCredentialsException
。
请注意,这被认为 不太安全。
来自 setHideUserNotFoundExceptions
Javadoc:
By default the AbstractUserDetailsAuthenticationProvider
throws a BadCredentialsException
if a username is not found or the password is incorrect. Setting this property to false
will cause UsernameNotFoundException
s to be thrown instead for the former. Note this is considered less secure than throwing BadCredentialsException
for both exceptions.
如果您选择这样做,下面是如何使用 setHideUserNotFoundExceptions
的示例
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(customUserDetailsService);
provider.setPasswordEncoder(customPasswordEncoder);
provider.setHideUserNotFoundExceptions(false) ;
return provider;
}
我正在尝试在 spring 引导 (2.5.3) 中进行基本身份验证,并在数据库中找不到用户时调用 UserNotFoundException。
@Override
public User findByUserName(String username){
try {
return (User) template.queryForObject("SELECT * FROM USERS WHERE email = ?",
new BeanPropertyRowMapper(User.class), username);
} catch (EmptyResultDataAccessException e) {
throw new UsernameNotFoundException("User not found");
}
}
但结果我收到消息“Bad Credential”。 BadCredential Exception 改变了我的异常。
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException ex) throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
//HttpStatus.FORBIDDEN
Map<String, Object> data = new HashMap<>();
data.put(
"timestamp",
Calendar.getInstance().getTime());
data.put(
"exception",
ex.getMessage());
System.out.println(ex.getClass());
response.getOutputStream()
.println(objectMapper.writeValueAsString(data));
}
class org.springframework.security.authentication.BadCredentialsException
我应该覆盖什么才能看到 UserNotFoundException 错误消息?
创建自定义 Auth 提供程序
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private Repository repository;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
User user = repository.findByUserName(name);
if(!encoder().matches(password, user.getPassword())){
throw new BadCredentialsException("Bad credentials");
}
return new UsernamePasswordAuthenticationToken(user, password,
Arrays.asList(new SimpleGrantedAuthority("USER_ROLE")));
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
就像那里解释的那样https://www.baeldung.com/spring-security-authentication-provider
您可以将 AuthenticationProvider
配置为在找不到用户名时抛出 UsernameNotFoundException
而不是 BadCredentialsException
。
请注意,这被认为 不太安全。
来自 setHideUserNotFoundExceptions
Javadoc:
By default the
AbstractUserDetailsAuthenticationProvider
throws aBadCredentialsException
if a username is not found or the password is incorrect. Setting this property tofalse
will causeUsernameNotFoundException
s to be thrown instead for the former. Note this is considered less secure than throwingBadCredentialsException
for both exceptions.
如果您选择这样做,下面是如何使用 setHideUserNotFoundExceptions
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(customUserDetailsService);
provider.setPasswordEncoder(customPasswordEncoder);
provider.setHideUserNotFoundExceptions(false) ;
return provider;
}