wuyouzhuguli/SpringAll · warning · AuthenticationServiceException

Authentication method not supported: {}

Error message

Authentication method not supported: {}

What it means

Spring Security's AuthenticationServiceException, thrown by SmsAuthenticationFilter.attemptAuthentication when postOnly is true (the default) and the HTTP method is not POST. The message is built by string concatenation, so the {} placeholder in the index is filled with the actual method (e.g., '... not supported: GET'). This mirrors Spring's own UsernamePasswordAuthenticationFilter behavior; the filter is wired to match only POST /login/mobile.

Source

Thrown at 38.Spring-Security-SmsCode/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. Submit the mobile login as an HTTP POST to /login/mobile.
  2. Ensure the front-end form/fetch uses method POST with the right Content-Type.
  3. Configure the filter chain / CORS to handle OPTIONS preflight before this filter.
  4. Only if intentional, set filter.setPostOnly(false) - not recommended for credential submission.

Example fix

// before
<form action="/login/mobile">  <!-- defaults to GET -->
  <input name="mobile"/>
</form>

// after
<form action="/login/mobile" method="post">
  <input name="mobile"/>
  <input name="smsCode"/>
</form>
Defensive patterns

Strategy: validation

Validate before calling

// front-end: only POST to the mobile login endpoint
async function smsLogin(mobile, smsCode) {
    if (!mobile || !smsCode) { showError('mobile and smsCode required'); return; }
    await fetch('/login/mobile', {
        method: 'POST',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({ mobile, smsCode })
    });
}

Prevention

When it happens

Trigger: Any non-POST request (GET, PUT, DELETE, OPTIONS preflight) to /login/mobile reaching SmsAuthenticationFilter.

Common situations: Front-end submits via GET or a misrouted fetch; developer tested the endpoint by typing the URL in the browser (GET); CORS preflight OPTIONS hits the filter because it is not excluded; the form action omits method="post".

Understand the failure class

Related errors


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