gafaelfawr.auth.generate_unauthorized_challenge(context, auth_type, exc=None, *, ajax_forbidden=False)#

Construct exception for a 401 response with AJAX handling.

This is a special case of generate_challenge() for generating 401 Unauthorized challenges. For these, the exception is optional, since there is no error and thus no error_description field if the token was simply not present.

  • context (RequestContext) – The incoming request.

  • auth_type (AuthType) – The type of authentication to request.

  • exc (Optional[InvalidTokenError], default: None) – An exception representing a bearer token error. If not present, assumes that no token was provided and there was no error.

  • ajax_forbidden (bool, default: False) – If set to True, check to see if the request was sent via AJAX (see Notes) and, if so, convert it to a 403 error.


The exception to raise, either a 403 (for AJAX) or a 401.

Return type:



If the request contains X-Requested-With: XMLHttpRequest, return 403 rather than 401. The presence of this header indicates an AJAX request, which in turn means that the request is not under full control of the browser window. The redirect ingress-nginx will send will therefore not result in the user going to the authentication provider properly, but may result in a spurious request from background AJAX that cannot be completed. That, in turn, can cause unnecessary load on the authentication provider and may result in rate limiting.

Checking for this header does not catch all requests that are pointless to redirect (image and CSS requests, for instance), and not all AJAX requests will send the header, but every request with this header should be pointless to redirect, so at least it cuts down on the noise. This corresponds to the invalid_token error in RFC 6750: “The access token provided is expired, revoked, malformed, or invalid for other reasons. The string form of this exception is suitable for use as the error_description attribute of a WWW-Authenticate header.