wuyouzhuguli/SpringAll · error · InternalAuthenticationServiceException

未找到与该手机号对应的用户

Error message

未找到与该手机号对应的用户

What it means

InternalAuthenticationServiceException thrown by SmsAuthenticationProvider.authenticate when userDetailService.loadUserByUsername(mobile) returns null. The principal carried by SmsAuthenticationToken is the mobile number, so the UserDetailService lookup is keyed by phone. Note: most Spring Security UserDetailsService implementations throw UsernameNotFoundException instead of returning null, so reaching this branch implies a custom implementation that swallows missing users.

Source

Thrown at 61.Spring-security-Permission/src/main/java/cc/mrbird/validate/smscode/SmsAuthenticationProvider.java:20

import cc.mrbird.security.browser.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

  1. Register the mobile number in whatever store UserDetailService reads from so loadUserByUsername(mobile) resolves.
  2. Verify UserDetailService actually loads by mobile (the query/filter must match the phone column), not by username.
  3. Confirm SmsAuthenticationToken.getPrincipal() is the mobile string (SmsAuthenticationFilter sets it from obtainMobile).
  4. Prefer throwing UsernameNotFoundException inside UserDetailService for unknown users (Spring convention) so the failure is surfaced at the right layer.
Defensive patterns

Strategy: validation

Validate before calling

// Before offering SMS login, verify the mobile is registered (if an endpoint exists).
const ok = await fetch(`/users/exists?mobile=${encodeURIComponent(mobile)}`).then(r=>r.json());
if (!ok.exists) { showError('该手机号未注册'); return; }

Try / catch

try { await smsLogin(mobile, code); }
catch (e) {
  if (/未找到与该手机号对应的用户/.test(e.message)) { promptRegister(mobile); }
  else handleError(e);
}

Prevention

When it happens

Trigger: The submitted mobile number is not registered; the UserDetailService queries by username column, not phone; the principal set in SmsAuthenticationFilter.obtainMobile is not the mobile string the service expects.

Common situations: User never signed up / no seed data for that phone; DB schema stores phone in a column the query ignores; SmsAuthenticationFilter wired with the wrong mobileParameter name; test environment missing user fixtures.

Related errors


AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14). Data as JSON: /api/errors/4ea092cc6b4ac590. Report an issue: GitHub.