dromara/Sa-Token · error · NotHttpDigestAuthException

10312

10312

Error message

no http digest auth

What it means

Thrown as NotHttpDigestAuthException (code 10312) by SaHttpDigestTemplate when a request does not carry a valid HTTP Digest 'Authorization' header. Before throwing, the template fills in default challenge parameters (realm, qop, random nonce/opaque, nc=00000001) and writes a 401 status plus a 'WWW-Authenticate' header so the browser can re-respond with Digest credentials. This is the standard Digest authentication failure / challenge flow, not a framework misconfiguration.

Source

Thrown at sa-token-core/src/main/java/cn/dev33/satoken/httpauth/digest/SaHttpDigestTemplate.java:82

    /**
     * 在校验失败时,设置响应头,并抛出异常
     * @param model Digest 参数对象
     */
    public void throwNotHttpDigestAuthException(SaHttpDigestModel model) {
        // 补全一些必须的参数
        model.realm = (model.realm != null) ? model.realm : SaHttpDigestModel.DEFAULT_REALM;
        model.qop = (model.qop != null) ? model.qop : SaHttpDigestModel.DEFAULT_QOP;
        model.nonce = (model.nonce != null) ? model.nonce : SaFoxUtil.getRandomString(32);
        model.opaque = (model.opaque != null) ? model.opaque : SaFoxUtil.getRandomString(32);
        model.nc = (model.nc != null) ? model.nc : "00000001";

        // 设置响应头
        SaHolder.getResponse()
                .setStatus(401)
                .setHeader("WWW-Authenticate", buildResponseHeaderValue(model));

        // 抛异常
        throw new NotHttpDigestAuthException().setCode(SaErrorCode.CODE_10312);
    }

    /**
     * 获取浏览器提交的 Digest 参数 (裁剪掉前缀)
     * @return 值
     */
    public String getAuthorizationValue() {

        // 获取前端提交的请求头 Authorization 参数
        String authorization = SaHolder.getRequest().getHeader("Authorization");

        // 如果不是以 Digest 作为前缀,则视为无效
        if(authorization == null || ! authorization.startsWith("Digest ")) {
            return null;
        }

        // 裁剪前缀并解码
        return authorization.substring(7);

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. Have the client answer the 401 challenge: read the WWW-Authenticate header, compute the Digest response (username, realm, nonce, uri, HA1/HA2 with qop), and resend with 'Authorization: Digest ...'
  2. If calling programmatically, use an HTTP client with built-in Digest support (e.g. Apache HttpClient's DigestScheme, OkHttp authenticator, curl --digest)
  3. If this endpoint should not require Digest auth, remove the @SaCheckHttpDigest annotation / skip the check() call
  4. In a global exception handler, catch NotHttpDigestAuthException and return the 401 response unchanged so the challenge header reaches the client

Example fix

// before (client sends nothing)
curl http://api.example.com/admin/data   // -> 401 + exception code 10312

// after (client responds to the Digest challenge)
curl --digest -u username:password http://api.example.com/admin/data
Defensive patterns

Strategy: try-catch

Validate before calling

String auth = SaHolder.getRequest().getHeader("Authorization");
boolean hasDigest = auth != null && auth.startsWith("Digest ");
if (!hasDigest) {
    // respond 401 with WWW-Authenticate instead of invoking check()
}

Try / catch

try {
    saTokenHttpDigestTemplate.check(model);
} catch (NotHttpDigestAuthException e) {
    // response already carries 401 + WWW-Authenticate; return it as-is so the client can retry with Digest credentials
    return;
}

Prevention

When it happens

Trigger: Calling saTokenHttpDigestTemplate.check(model) (directly or via the @SaCheckHttpDigest annotation interceptor) on a request whose Authorization header is missing or does not start with the 'Digest ' prefix. The method getAuthorizationValue() returns null/invalid, so check() populates the challenge model, sets the 401 + WWW-Authenticate response, and throws.

Common situations: First request from a browser or API client with no credentials (expected challenge); calling a Digest-protected API from curl/Postman/HttpClient without an Authorization header; a client that sends Basic auth instead of Digest; proxies stripping the Authorization header; test cases that forget to compute a Digest response.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/7158064c54a78a2d. Report an issue: GitHub.