wuyouzhuguli/SpringAll · error · AuthenticationServiceException

Authentication method not supported: {method}

Error message

Authentication method not supported: {method}

What it means

AuthenticationServiceException thrown by SmsAuthenticationFilter.attemptAuthentication when postOnly=true (the default) and the HTTP method of the request to /login/mobile is not POST. The filter is constructed with AntPathRequestMatcher("/login/mobile", "POST"), so SMS login is POST-only by design.

Source

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

import javax.servlet.http.HttpServletResponse;

public class SmsAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    public static final String MOBILE_KEY = "mobile";

    private String mobileParameter = MOBILE_KEY;
    private boolean postOnly = true;


    public SmsAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login/mobile", "POST"));
    }


    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }

        String mobile = obtainMobile(request);

        if (mobile == null) {
            mobile = "";
        }

        mobile = mobile.trim();

        SmsAuthenticationToken authRequest = new SmsAuthenticationToken(mobile);

        setDetails(request, authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
    }

View on GitHub (pinned to 614d2578d9)

Solutions

  1. Send the SMS login request as POST to /login/mobile with mobile (and smsCode) in the body.
  2. Register a CorsFilter / CorsConfigurationSource that handles OPTIONS before Spring Security, so preflights do not reach SmsAuthenticationFilter.
  3. If you genuinely need other verbs, set the filter's postOnly=false (not recommended for authentication).

Example fix

// before
// fetch('/login/mobile?mobile=13800000000&smsCode=123456')

// after
fetch('/login/mobile', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: 'mobile=13800000000&smsCode=123456'
});
Defensive patterns

Strategy: validation

Validate before calling

// Guard the verb before calling.
function smsLogin(mobile, code) {
  return fetch('/login/mobile', {
    method: 'POST', // always POST
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({ mobile, smsCode: code })
  });
}

Try / catch

try { await smsLogin(mobile, code); }
catch (e) {
  if (/not supported/i.test(e.message)) { /* ensure POST was used; check CORS/OPTIONS */ }
  else handleError(e);
}

Prevention

When it happens

Trigger: Any GET/PUT/DELETE/etc. request to /login/mobile; an OPTIONS preflight from a cross-origin browser that is not handled by CORS infrastructure and reaches the filter; a frontend form using method="get".

Common situations: Frontend axios/fetch defaulting to GET; misconfigured CORS so the OPTIONS preflight hits the auth filter instead of a CorsFilter; API client using the wrong verb; browser navigation/form defaulting to GET.

Understand the failure class

Related errors


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