wuyouzhuguli/SpringAll · error · InternalAuthenticationServiceException
未找到与该手机号对应的用户
Error message
未找到与该手机号对应的用户
What it means
Spring Security's InternalAuthenticationServiceException is thrown by SmsAuthenticationProvider.authenticate when userDetailService.loadUserByUsername(mobile) returns null during SMS-based login. It signals an authentication-service-layer problem (as opposed to a normal bad-credentials rejection) and surfaces during the custom SMS authentication flow where the principal is the mobile phone number. The contract of UserDetailsService actually expects a UsernameNotFoundException when no user exists, so a null return is itself an implementation smell that this guard compensates for.
Source
Thrown at 65.Spring-Security-OAuth2-Config/src/main/java/cc/mrbird/security/validate/smscode/SmsAuthenticationProvider.java:20
import cc.mrbird.security.service.UserDetailService;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
public class SmsAuthenticationProvider implements AuthenticationProvider {
private UserDetailService userDetailService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsAuthenticationToken authenticationToken = (SmsAuthenticationToken) authentication;
UserDetails userDetails = userDetailService.loadUserByUsername((String) authenticationToken.getPrincipal());
if (userDetails == null)
throw new InternalAuthenticationServiceException("未找到与该手机号对应的用户");
SmsAuthenticationToken authenticationResult = new SmsAuthenticationToken(userDetails, userDetails.getAuthorities());
authenticationResult.setDetails(authenticationToken.getDetails());
return authenticationResult;
}
@Override
public boolean supports(Class<?> aClass) {
return SmsAuthenticationToken.class.isAssignableFrom(aClass);
}
public UserDetailService getUserDetailService() {
return userDetailService;
}
public void setUserDetailService(UserDetailService userDetailService) {View on GitHub (pinned to 614d2578d9)
Solutions
- Verify the UserDetailsService used by SmsAuthenticationProvider actually returns a UserDetails for the submitted mobile — check the DB query and the column it matches against.
- Make loadUserByUsername throw new UsernameNotFoundException(...) instead of returning null, which is the documented contract; let Spring's normal bad-credentials flow handle unknown users rather than surfacing an internal-service exception.
- Ensure the mobile value passed as principal is normalized (trim, +prefix, country code) identically to how it is stored when the SMS code was generated, so the lookup key matches.
- If self-registration is intended, register/link the user on first SMS login instead of failing; otherwise return a clear user-facing 'unregistered mobile' message.
- Confirm the correct UserDetailsService bean is wired into SmsAuthenticationProvider (userDetailService setter/field injection), not the default JDBC/in-memory one that has no mobile mapping.
Example fix
// before
UserDetails userDetails = userDetailService.loadUserByUsername((String) authenticationToken.getPrincipal());
if (userDetails == null)
throw new InternalAuthenticationServiceException("未找到与该手机号对应的用户");
// after — let the service obey its contract and surface a normal auth failure
UserDetails userDetails;
try {
userDetails = userDetailService.loadUserByUsername((String) authenticationToken.getPrincipal());
} catch (UsernameNotFoundException e) {
throw new BadCredentialsException("未找到与该手机号对应的用户", e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before authentication, confirm a user is linked to the mobile
boolean registered = userService.existsByMobile(mobile);
if (!registered) {
return "该手机号尚未注册";
}
// then proceed with the SmsAuthenticationToken flow Type guard
// Narrow before relying on the cast/null — validate the principal is a mobile string
private boolean isMobilePrincipal(Authentication auth) {
return auth.getPrincipal() instanceof String
&& ((String) auth.getPrincipal()).matches("1\\d{10}");
} Try / catch
try {
Authentication result = authenticationManager.authenticate(token);
} catch (InternalAuthenticationServiceException | UsernameNotFoundException e) {
// map to a clean user-facing 'unregistered mobile' failure
throw new BadCredentialsException("手机号未注册", e);
} catch (BadCredentialsException e) {
// normal wrong-credentials path
throw e;
} Prevention
- Make your UserDetailsService throw UsernameNotFoundException instead of returning null, honoring the documented contract.
- Normalize the mobile (trim, country code) identically at send-code and authenticate time so lookups always hit.
- Wire the dedicated SMS UserDetailsService bean into SmsAuthenticationProvider explicitly to avoid falling back to a default with no mobile mapping.
- Register/link users on first SMS login if self-service is intended.
When it happens
Trigger: An SMS login request reaches the provider (a SmsAuthenticationToken is submitted), loadUserByUsername is invoked with the mobile number as the principal, and the backing UserDetailsService returns null — e.g. the mobile is unregistered, the user record was deleted, or the service queries the wrong column. The null check at line 20 then throws this exception instead of producing a populated authentication token.
Common situations: The mobile-to-user mapping in the database is missing or misconfigured (storing the phone under a different column than the query reads); a fresh/anonymous user attempts SMS login before any account is linked to that number; a test environment seeded users without phone fields; or the custom UserDetailsService implementation forgot to throw UsernameNotFoundException and silently returns null.
Related errors
- Authentication method not supported: {}
- Authentication method not supported: {method}
- 未找到与该手机号对应的用户
- Authentication method not supported: {method}
- 未找到与该手机号对应的用户
AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14).
Data as JSON: /api/errors/830d765bf061f19e.
Report an issue: GitHub.