What HTTP code should I use for a third party authentication failure?

I'd go with 400, it meets the semantic requirement. The user supplied some bad data. As you say a 401 / 403 implies an issue between the user and your site, not your site and some other application.

Section 1 of the HTTP 1.1 RFC states:

Introduction

Each Hypertext Transfer Protocol (HTTP) message is either a request or a response. A server listens on a connection for a request, parses each message received, interprets the message semantics in relation to the identified request target, and responds to that request with one or more response messages. A client constructs request messages to communicate specific intentions, examines received responses to see if the intentions were carried out, and determines how to interpret the results. This document defines HTTP/1.1 request and response semantics in terms of the architecture defined in [RFC7230].

Ergo the definition of status codes are between a client and a server. To me that means pick the one that makes the best sense for other (server to server, backend, etc) interactions.

All the other exotics offered here are just going to confuse the consumer of the service.


You can use status code HTTP status code - 407 (Proxy Authentication Required). From Mozilla Developers Reference:

The HTTP 407 Proxy Authentication Required client error status response code indicates that the request has not been applied because it lacks valid authentication credentials for a proxy server that is between the browser and the server that can access the requested resource.

Your backend-application is acting like a proxy to 3rd party API, so it is OK to use 407 in this case.


The question seems to imply the authentication failure is the fault of the client making the request. In that case, if I had to pick a code, I would probably choose to return 403 Forbidden.

RFC 7231 §6.5.3 describes the 403 code as follows:

The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it. A server that wishes to make public why the request has been forbidden can describe that reason in the response payload (if any).

If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. However, a request might be forbidden for reasons unrelated to the credentials.

An origin server that wishes to "hide" the current existence of a forbidden target resource MAY instead respond with a status code of 404 (Not Found).

This status code is commonly used as a generic 'authentication failed' response and isn't likely to trigger any specific authentication mechanism, like 401 can compel a browser to show a username/password prompt. The specific reason why authentication failed can be described in the response body, either in a machine-readable form (e.g. JSON or XML), or as a human-readable document (e.g. HTML).

Code 400 isn't the worst possible choice here, but it's rather generic.


407 is not correct. In this case, your code is the proxy and it is authenticated. It is a foreign system that is not authenticated.

401 is reasonable but it is misleading about what is not authenticated since the client is authenticated to your system. This also does not work if your foreign auth is deferred until after a 100Continue.

400 is not correct since the request was valid in format but the auth failed at the foreign agent.

All the other 4xx responses are easily dismissed as not applicable here.

So, that leaves 403 Forbidden which in my opinion is your only real option in this case:

403 Forbidden The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401, the client's identity is known to the server. Responding also with a status message that indicates "root cause" of failure may be suitable in this case too. It really depends on the security disposition of your application.

My $.02