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

Support for route authorization #3275

Closed
irothschild opened this issue Jul 31, 2016 · 9 comments
Closed

Support for route authorization #3275

irothschild opened this issue Jul 31, 2016 · 9 comments
Assignees
Labels
Milestone

Comments

@irothschild
Copy link

@irothschild irothschild commented Jul 31, 2016

When using dynamic hypermedia responses, it's nice to be able to check for authorization for various routes based on the current request credentials. Unfortunately, the code that does the access (entity and scope) checks is not currently exposed so there isn't a simple way to do this.

I'd love to see a method route.authorizeRequest(request) or route.authorize(request.auth).

@hueniverse
Copy link
Contributor

@hueniverse hueniverse commented Aug 23, 2016

I need an example of what this would look like.

@irothschild
Copy link
Author

@irothschild irothschild commented Aug 23, 2016

It's basically refactoring code in internals.Authenticator validate() in auth.js and exposing the functionality from a route instance. Something like this (which isn't working code):

Route.prototype.authorizeRequest = function(request) {       
      // authorize a route based on auth in the request
      var credentials = request.auth.credentials;
      var config = route.settings.auth;

       const requestEntity = (credentials.user ? 'user' : 'app');

        const scopeErrors = [];
        for (let i = 0; i < config.access.length; ++i) {
            const access = config.access[i];

            // Check entity

            const entity = access.entity;
            if (entity &&
                entity !== 'any' &&
                entity !== requestEntity) {

                continue;
            }

            // Check scope

            let scope = access.scope;
            if (scope) {
                if (!credentials.scope) {
                    scopeErrors.push(scope);
                    continue;
                }

                scope = internals.expandScope(request, scope);
                if (!internals.validateScope(credentials, scope, 'required') ||
                    !internals.validateScope(credentials, scope, 'selection') ||
                    !internals.validateScope(credentials, scope, 'forbidden')) {

                    scopeErrors.push(scope);
                    continue;
                }
            }

            return True;  // allow access
        }

        return False; // authorization denied
}

@hueniverse
Copy link
Contributor

@hueniverse hueniverse commented Aug 23, 2016

I don't understand the point of this. If the request has credentials, they would have already been verified against the scope and entity. Have you looked at the auth.test() method?

@irothschild
Copy link
Author

@irothschild irothschild commented Aug 23, 2016

It's for testing authorization for other routes. So in my hypermedia reply, I can include links to other endpoints that the user has permission to access.

@hueniverse
Copy link
Contributor

@hueniverse hueniverse commented Aug 25, 2016

You are going to get the routing table, then try each one? sounds awful.

@irothschild
Copy link
Author

@irothschild irothschild commented Aug 25, 2016

Trying each route in the table would be like having a web page with links to every other page and resource on the site. Sounds awful. No one would do that.

I have a short list of related routes (by id). For a website analogy, imagine showing a few extra links on a webpage if a user has admin permissions.

I'm not building a web site, I'm building a hypermedia API. Some of our endpoints are 'private' features that are only exposed to users with the right credentials.

@devinivy
Copy link
Member

@devinivy devinivy commented Aug 25, 2016

I can imagine the use-case. This isn't the first time folks have asked to expose the logic used to validate access. I personally think it makes sense to expose it given that auth.test() already exposes the "other side" of auth.

@thebergamo
Copy link

@thebergamo thebergamo commented Aug 25, 2016

This request, sounds a good point, because sometimes you need to redirect the user to another endpoint internally and test if the user have roles to access its really useful.

@hueniverse hueniverse self-assigned this Aug 26, 2016
@hueniverse hueniverse added this to the 15.0.0 milestone Aug 26, 2016
@hueniverse
Copy link
Contributor

@hueniverse hueniverse commented Aug 26, 2016

As you can see from the documentation, this has to be pretty limited.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants