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
- 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 ...'
- If calling programmatically, use an HTTP client with built-in Digest support (e.g. Apache HttpClient's DigestScheme, OkHttp authenticator, curl --digest)
- If this endpoint should not require Digest auth, remove the @SaCheckHttpDigest annotation / skip the check() call
- 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
- Configure API clients with Digest-aware authentication (curl --digest, HttpClient DigestScheme) rather than sending raw requests
- In a global exception handler, treat NotHttpDigestAuthException as a 401 challenge, not a 500 error
- Never swallow the 401 status the template already set before throwing
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
- UsernameAndPassword 不能为空
- UsernameAndPassword 格式错误,正确格式为:username:password
- 未配置全局 Http Digest 认证参数
- 全局 Http Digest 认证参数配置错误,格式应如:username:password
- 注解参数配置错误,格式应如:username:password
AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14).
Data as JSON: /api/errors/7158064c54a78a2d.
Report an issue: GitHub.