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

Clients are not challenged when they are expected to be #106

Open
nuxwin opened this issue Dec 22, 2015 · 5 comments
Open

Clients are not challenged when they are expected to be #106

nuxwin opened this issue Dec 22, 2015 · 5 comments

Comments

@nuxwin
Copy link
Contributor

nuxwin commented Dec 22, 2015

@weierophinney

My #92 fix was wrong after all... It prevent challenge of clients when needed...

The problem coming from the #92 fix

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

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

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

Now, let's imagine the following scenario: A client requests the following URI https://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 http authentication adapter will be called (That adapter matches the 'basic' authentication 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 that the #92 fix tried to solve

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

Thus, current design (assuming that the fix referenced by #92 is reverted) involve challenging clients, 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 clients (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. We are currently mapping API/VERSION to authentication type only. We should maybe add another map allowing to mark specific resource as public. This would involve matching of the controller, action and method.

@weierophinney
Copy link
Member

@nuxwin Just a question: are you aware of the authorization.deny_by_default setting? Essentially, if you set this to boolean true, your API is private except for resources you whitelist. If you look in the config/module.config.php file of this repo, you can see how to do that.

Unfortunately, we don't have a UI for when that flag is enabled, which means you would then need to manually create the rules when you want to whitelist anything. However, it seems like it might fit the needs you're indicating.

@nuxwin
Copy link
Contributor Author

nuxwin commented Dec 22, 2015

@weierophinney

Sure, but you forgot that authorization always comes after authentication and thus, the clients are always challenged (e.g. in case of http basic,digest authentication). That our main problem here. You can set as many autorization rules as you want, the problem will remain same as long as we will not make the authentication layer aware of public resources.

To resume, this assertion Essentially, if you set this to boolean true, your API is private except for resources you whitelist is false in case of HTTP basic, digest authentication because clients are challenged before the authorization process (assuming that #92 is reverted to go back to your initial design).

For your sentence about the UI, we could add that ;)

@nuxwin
Copy link
Contributor Author

nuxwin commented Dec 22, 2015

@weierophinney

A simple solution which would solve all problems would be to apply authorization rules, even if an authentication adapter returns a response. In such specific case, the authorization listener could just override the response (status code and headers) if after all the GuestIdentity is authorized to access the resource that is marked as public.

I'll provide some patches and tests for this.

nuxwin added a commit to nuxwin/zf-mvc-auth that referenced this issue Dec 23, 2015
nuxwin added a commit to nuxwin/zf-apigility that referenced this issue Dec 23, 2015
Fix unit tests (deprecated hydrator)
nuxwin added a commit to nuxwin/zf-apigility that referenced this issue Dec 23, 2015
Fix unit tests (deprecated hydrator)
@nuxwin
Copy link
Contributor Author

nuxwin commented Dec 25, 2015

Working on this ATM, implementing a map which will allows to enable authentication on specific routes.

@weierophinney
Copy link
Member

This repository has been closed and moved to laminas-api-tools/api-tools-mvc-auth; a new issue has been opened at laminas-api-tools/api-tools-mvc-auth#10.

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