wuyouzhuguli/SpringAll · error · InternalAuthenticationServiceException

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

Error message

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

What it means

Thrown by SmsAuthenticationProvider.authenticate (Logout project) as InternalAuthenticationServiceException when userDetailService.loadUserByUsername(mobile) returns null — no account for that mobile. Reachability depends on the custom UserDetailService, since Spring's contract usually throws UsernameNotFoundException instead of returning null.

Source

Thrown at 60.Spring-Security-Logout/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. Have loadUserByUsername throw UsernameNotFoundException for unknown users instead of returning null.
  2. Normalize the mobile number consistently between registration and lookup.
  3. Ensure the user store contains the submitted mobile.
  4. Surface a friendly 'not registered' message via the failure handler.

Example fix

// before
if (userDetails == null)
    throw new InternalAuthenticationServiceException("未找到与该手机号对应的用户");

// after
// throw UsernameNotFoundException in the service; map it to a friendly auth failure.
Defensive patterns

Strategy: try-catch

Validate before calling

// optional pre-check that the mobile is registered
if (!userService.existsByMobile(mobile)) { throw new UsernameNotFoundException(mobile); }

Type guard

// narrow a loaded user
if (userDetails == null || !userDetails.isEnabled()) {
    throw new InternalAuthenticationServiceException("未找到与该手机号对应的用户");
}

Try / catch

try {
    authenticationManager.authenticate(new SmsAuthenticationToken(mobile));
} catch (InternalAuthenticationServiceException | UsernameNotFoundException e) {
    // map to friendly 'mobile not registered' response
}

Prevention

When it happens

Trigger: SMS login with an unregistered mobile; UserDetailService returns null instead of throwing; mobile normalized differently than stored.

Common situations: Typo in the number; user never provisioned; +86 prefix mismatch; test env missing seed data.

Related errors


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