Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

Apigility - Authentication - Per Api authentication adapter - Authorization problem #92

Closed
nuxwin opened this issue Jul 19, 2015 · 3 comments

Comments

@nuxwin
Copy link
Contributor

nuxwin commented Jul 19, 2015

Don't know if this is more related to this module so ;)

See zfcampus/zf-apigility-skeleton#104:

  • HTTP auth is updating the response instance with a 401 status when no credentials are passed, making it impossible to have public parts of an API that uses HTTP authentication.
@nuxwin
Copy link
Contributor Author

nuxwin commented Jul 21, 2015

@weierophinney

I'll do a PR in few minutes for the referenced bug. Changes made will be done in the ZF\MvcAuth\Authentication\HttpAdapter.

Here I'll simply mimic the OAuth adapter behavior. E.g: When no credential were present at all, we just return a guest identity. Then, this solves the issue.

The ZF\Apigility\MvcAuth\UnauthenticatedListener will simply return due to the absence of the authentication result and thus, the authorization process for guest identity will be performed as it should.

BTW: To be able to reproduce the issue referenced here, only one Basic auth adapter must be configured.

@PowerKiKi
Copy link

I fail to see how it solve the issue. IMHO, you have to know whether the request is for a private or public API in order to either return a 401 or a successful response. How can you differentiate between those two cases before routing (and thus authentication configuration) ?

@nuxwin
Copy link
Contributor Author

nuxwin commented Dec 22, 2015

@weierophinney

My fix was wrong after all... It prevent challenge of client when needed...

...
'zf-mvc-auth' => [
    'authentication' => 

        'adapters' => [
            'http' => [
                // HTTP auth adapter configuration
            ],
            'whatever' => [
                // Whatever auth adapter configuration
            ],
        ],

        'map' => [
            'API/VERSION1' => 'basic',
            'API/VERSION2 => 'whatevertype'
        ]
    ]
]
...

Now, let imagine the following scenario: A client request the following URI /host.tld/API/VERSION1 (here, the matching authentication type is basic). No Authorization header is sent by the client.

Then, the following will occurs in the default authentication listener:

  • getTypeFromRequest() will not be called (we have already an authentication type which is basic)
  • pre-flight auth tasks will not be called on auth adapter. In that case, this involve that the client will not - be challenged (no 401 status code, nor WWW-Authenticate header)
  • authenticate() method on the MVC authentication adapter will be called (That adapter matches the 'basic' authentication type type)

At this point, if the mvc http adapter don't find the Authorization header, it will simply return a GuestIdentity. So, later on, the authorization listener will simply set a 403 status code if GuestIdentity is not allowed to access the resource.

The problem here, is that the authentication layer don't known if a resource is private or public. That layer only known which authentitcation type is available for a specific API.

Thus, current design (assuming that the fix referenced by #92 is reverted) involve challenging client, whatever the resource is private or not. This means here that an API is just either public or private. There is no concept of public and private resources at this level.

This is bad because if someone want provide both public and private resources through the same API, it cannot because client (even for public resources) will be challenged. That was the point of my #92 fix that is wrong because it delegate challenge phase to the authorization layer, which is only able to send 403 status code. This is normal because the authorization layer must not be concerned about authentication.

A way to resolve that problem would be to allow the developer to mark specific resource as public (no authentication required). Now here, we have to think how.

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

No branches or pull requests

2 participants