I am building a service which acts as a proxy to third party data providers for the end-user. My service uses tokens for authorization and if the user does not have a valid token it responds with
401 Unauthorized. If the token is valid but access to the resource is denied my service responds with
The service fetches data from third party data providers. These data providers use the same response codes (401/403). When such a token has expired, the end-user must enter their credentials to that service again so that my service can request new tokens from the third party providers.
If I just forward the 401/403 from the third party data provider to my end-user, they will not be able to know if authorization failed towards my service or the third party. The frameworks I am using does not allow me to change the message nor send a body with the response.
I have been pondering which status code I can use and thought of
511 Network Authentication Required. This code is used by "proxies" and my service does act as a proxy, although perhaps not in the way a "normal" network proxy does.
511 be a reasonable status code to use or is there something better?
Your use is pretty much what oauth is designed to handle; a client application interacting with resource servers on behalf of a resource owner.
There are two authentication points, initial authentication/access token acquisition and refresh token acquisition. Presumably, you have figured out how to authenticate the user on first access to the resource server(s).
When the access token expires, you are supposed to use a refresh token to request a new access token (on behalf of the user) so the current and future requests can proceed without resource owner interaction. If the authentication servers for the resources that you are accessing are providing refresh tokens, you should hold on to these and use these to acquire new access tokens when requests fail (and not send a 401 back).
Authorization servers are not required to send refresh tokens. In that case, a 401 from a resource server should trigger the initial authorization flow again (to retrieve a new access token). Normally, that's a 302 redirect to the authorization server with the client_id, scope, etc. I know you said that you cannot modify the response body but, since you're considering the 511 response code, you must be able to issue a 302.
I would suggest, if you are in fact using oauth for your own app as well, that you never issue a 401 for an expired token but always either use the refresh token to regain access to the resource server (if available) or redirect to the appropriate authorization endpoint to continue the request.