macrozheng/mall · error · UsernameNotFoundException
用户名或密码错误
Error message
用户名或密码错误
What it means
This is an inline UserDetailsService @Bean defined inside the mall-demo module's SecurityConfig, used by the demo app's authentication manager. It builds a UmsAdminExample criterion on username, runs umsAdminMapper.selectByExample, and throws UsernameNotFoundException when no row is found. Unlike the production mall-admin implementation, the returned AdminUserDetails is constructed with only the admin record and NO resourceList (no authorities are attached), so this demo path grants no granular resource permissions.
Source
Thrown at mall-demo/src/main/java/com/macro/mall/demo/config/SecurityConfig.java:56
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
//获取登录用户信息
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UmsAdminExample example = new UmsAdminExample();
example.createCriteria().andUsernameEqualTo(username);
List<UmsAdmin> umsAdminList = umsAdminMapper.selectByExample(example);
if (umsAdminList != null && umsAdminList.size() > 0) {
return new AdminUserDetails(umsAdminList.get(0));
}
throw new UsernameNotFoundException("用户名或密码错误");
}
};
}
}
View on GitHub (pinned to 0504e86b1f)
Solutions
- Confirm the demo's datasource (application.yml in mall-demo) points at a database populated with ums_admin seed rows, and that the test username exists there.
- Check umsAdminMapper is the correct MyBatis mapper and that the UmsAdminExample criterion uses the exact username column comparison (andUsernameEqualTo).
- If the demo should not authenticate against ums_admin, replace this UserDetailsService with an in-memory user (User.withUsername(...).password(...).roles(...)) for local testing.
- Provide the demo with at least one seeded admin row so selectByExample returns a non-empty list.
- Return AdminUserDetails with an explicit authorities/resource list if demo endpoints are role-protected, otherwise authorization may fail downstream.
Example fix
// before:
if (umsAdminList != null && umsAdminList.size() > 0) {
return new AdminUserDetails(umsAdminList.get(0));
}
throw new UsernameNotFoundException("用户名或密码错误");
// after (fail closed with authorities, avoid leaking the lookup miss):
if (umsAdminList == null || umsAdminList.isEmpty()) {
throw new UsernameNotFoundException("用户名或密码错误");
}
UmsAdmin admin = umsAdminList.get(0);
List<UmsResource> resources = umsResourceMapper
.selectByExample(new UmsResourceExample()); // or by admin id
return new AdminUserDetails(admin, resources); Defensive patterns
Strategy: validation
Validate before calling
// Validate the lookup result before returning UserDetails so the demo never relies
// on the exception for control flow, and so the cause is easy to diagnose.
List<UmsAdmin> rows = umsAdminMapper.selectByExample(example);
if (rows == null || rows.isEmpty()) {
LOGGER.warn("demo login: no admin row for username={}", username);
throw new UsernameNotFoundException("用户名或密码错误");
}
UmsAdmin admin = rows.get(0); Try / catch
// In the demo's protected flow, catch AuthenticationException once and redirect
// to login instead of letting it bubble as a 500.
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(username, password));
} catch (AuthenticationException e) {
LOGGER.warn("demo auth failed for {}: {}", username, e.getMessage());
redirect("/login?error=1");
} Prevention
- Point mall-demo at a database seeded with at least one ums_admin row before exercising protected endpoints.
- If the demo is for local exploration only, replace the DB-backed UserDetailsService with an in-memory User builder so a missing table cannot break login.
- Attach authorities to AdminUserDetails in the demo too, so downstream @PreAuthorize checks behave the same as in production.
When it happens
Trigger: Any authentication against the demo app where the submitted username has no matching row in ums_admin; invoking an endpoint on mall-demo protected by the demo SecurityConfig while unauthenticated with a non-existent principal; running the demo against a database whose ums_admin table is empty.
Common situations: Running mall-demo pointed at a DB that was not loaded with the seed admin users; mistyping the demo login username; the demo's spring.datasource pointing at the wrong schema so umsAdminMapper.selectByExample returns an empty list; testing against a fresh H2/in-memory DB.
Related errors
AI-assisted analysis of macrozheng/mall@0504e86b1f (2026-08-13).
Data as JSON: /api/errors/bec631f3a397fc5d.
Report an issue: GitHub.