Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add handling for missing Authorization header (send a 401 on authorization failure if no identity is asserted) #15

Open
weierophinney opened this issue Dec 31, 2019 · 11 comments

Comments

@weierophinney
Copy link
Contributor

Apigility-specific issue:
When submitting a request where authorization is required (e.g., admin menu -> authorization -> GET) is checked and no Authorization header is provided a 403 is returned rather than a 401.

Because no identity is asserted by the original request the appropriate response would (from an "API as a black box" perspective) be a 401.

Due to the current authorization flow in Apigility a 403 is returned because a Guest Identity (default identity should authentication not happen) is not allowed to perform the action that an Authenticated Identity can perform.

This request is to add in some kind of listener to intercept the request and return a 401 when the guest identity is not allowed to perform an action and authorization is checked in the admin UI.


Originally posted by @jackdpeterson at zfcampus/zf-mvc-auth#97

@weierophinney
Copy link
Contributor Author

This is fixed in #83


Originally posted by @dorongutman at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

This is not quite fixed in #83. Per discussions on IRC with @weierophinney and @nuxwin some additional configuration options are under consideration to send a 401 instead of a 403 when the authorization header is not provided for a resources that has the appropriate authorization header checked as an optional configuration parameter or as an external listener add-on (the purpose of this issue). The problem is that a guest identity is assumed to be asserted as a default in Apigility despite the HTTP request not making that kind of assertion as to its identity (via authorization header). This leads to an unintuitive 403 forbidden rather than a 401 unauthorized.

Example 1 - No headers provided
GET /protected-resource HTTP/1.1
Host: www.example.local
Cache-Control: no-cache

Response: 403 Forbidden

################

Example 2 - Bad headers provided:
GET /protected-resource HTTP/1.1
Host: www.example.local
Authorization: Bearer badHeader
Cache-Control: no-cache

Response: 401

Example 1, which would be default request which may trigger an authentication event on a client-side application would not occur. Instead the client-side application would believe that its locally stored credentials (if applicable) were in fact not authorized to access that resource. In reality though, no header was sent on behalf of the client-side application.

Example 2, which is the poor-man's workaround client-side is to first append protected-resource requests with a bogus header when not-yet authenticated.

Yes, there are client-side workarounds;however, the current situation leads to an unintuitive 403 response that is unique to Apigility in that it has to do exclusively with how Apigility is processing its default identity assignment and then performing an authorization request against the default identity (rather than immediately returning a 401).


Originally posted by @jackdpeterson at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

Same issue when trying to integrate angular-http-auth which expects 401 when there is no token for an API that requires one. But in practice we get a 403 which won't work as expected on the frontend side.


Originally posted by @PowerKiKi at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

There are several issues and PR around this topic over the last few months. That seems to indicate that the situation is not clear and/or not tested properly:

I think those are the HTTP status that we should expect:

No credentials Invalid credentials Correct credentials
protected API 401 401 200
public API 200 200 200

Is there a discussion somewhere that we could follow to track the progress on this issue ?


Originally posted by @PowerKiKi at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

Well, I may be a bit biased ... but I think #97
zfcampus/zf-mvc-auth#97 is an issue that
clearly that captures what the unintuitive 403 Forbidden problem. The
comment below with the expected table makes sense to me; however, it is not
how Apigiliy is currently designed to handle authentication / authorization
without a backwards compatibility break.

I agree that this needs a little more love in terms of an optional switch
to return a 401 when Guest Identity is provided (but not asserted by the
requestor) against a protected resource. My workaround at the moment on
client-side JS involves doing some extra detection steps to determine if I
have credentials stored and so forth when intercepting 40[1,3] responses
from the API before re-authenticating and re-submitting requests.

On Tue, Sep 22, 2015 at 1:34 AM, Adrien Crivelli [email protected]
wrote:

There are several issues and PR around this topic over the last few
months. That seems to indicate that the situation is not not clear and/or
not tested properly:

I think those are the HTTP status that we should expect:
No credentials Invalid credentials Correct credentials protected API 401
401 200 public API 200 200 200

Is there a discussion somewhere that we could follow to track the progress
on this issue ?


Reply to this email directly or view it on GitHub
zfcampus/zf-mvc-auth#97 (comment)
.

Jack Peterson
[email protected]
(425) 372 - 8514 (Cell)


Originally posted by @jackdpeterson at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

@PowerKiKi

The problem with your approach is that you have either a public API or private API while in most cases, an API will provide both: public and private resources.


Originally posted by @nuxwin at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

@nuxwin I may have expressed myself poorly, when I wrote "API", what I really meant was "one specific route in a single API", or in Apigility parlance "one specific RPC or REST service". But all of that doesn't change much the point I was trying to make: Apigilty behavior is wrong and unclear and it should be fixed IMHO.


Originally posted by @PowerKiKi at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

@PowerKiKi

You exactly meant: zfcampus/zf-mvc-auth#106 right?


Originally posted by @nuxwin at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

Yes, I had the same issue as described in #106. And it is still not solved AFAIK.

But please try to refrain from copy/pasting very similar text on several issues. That makes it very hard to follow the discussion. IMHO #106 is a duplicate of this issue and should not have been opened.


Originally posted by @PowerKiKi at zfcampus/zf-mvc-auth#97 (comment)

@weierophinney
Copy link
Contributor Author

@PowerKiKi

Copy/pasting? #106 is more concerned about reverting #92 which break initial design. Of course, I tried to explain the #92 purpose which is wrong after all, and profited to give my thinking about a solution for supporting public/private resources over same API. But right, there is many issues related to same domain. The problem is that ATM, there is nothing proposed (from implementation point of view).


Originally posted by @nuxwin at zfcampus/zf-mvc-auth#97 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant