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

Whitelist endpoints for OAuth #11

Closed
nurbs999 opened this issue Apr 26, 2016 · 11 comments
Closed

Whitelist endpoints for OAuth #11

nurbs999 opened this issue Apr 26, 2016 · 11 comments

Comments

@nurbs999
Copy link

I have 'Authorizer 2.5.0' and 'WP REST API - OAuth 1.0a Server 0.2.1' running.
I set 'Public Access' to 'Only logged in users can see the site' within Authorizer Options. I want to secure my REST API calls via OAuth but I get redirected to wp-login.php when I send a GET request to the OAuth discovery endpoint /wp-json.
It should respond with a JSON Object containing the authentication urls, routes etc needed for OAuth authentication.

@nurbs999
Copy link
Author

I think I found a quick fix for this:

Since /wp-json is the endpoint for the first OAuth1 request, this can be whitelisted (authorizer.php: 1212)

$has_access = (
        // Always allow access if WordPress is installing
        ( defined( 'WP_INSTALLING' ) && isset( $_GET['key'] ) ) ||
        // Always allow access to admins
        ( current_user_can( 'create_users' ) ) ||
        // Allow access if option is set to 'everyone'
        ( $auth_settings['access_who_can_view'] == 'everyone' ) ||
        // Allow access to approved external users and logged in users if option is set to 'logged_in_users'
        ( $auth_settings['access_who_can_view'] == 'logged_in_users' && $this->is_user_logged_in_and_blog_user() && $this->is_email_in_list( $current_user->user_email, 'approved' ) ) ||
        // Bypass authentication for request to /wp-json
        // This is needed to implement OAuth1
        ( stripos(strrev($_SERVER["REQUEST_URI"]), "nosj-pw/") === 0)
      );

Working with strrev here seems faster: http://stackoverflow.com/a/2137556
Maybe there is a more elegant way of checking the request URI since I don't really like working with $_SERVER.

@nurbs999 nurbs999 changed the title Endpoint /wp-json fails with Authorizer & OAuth Whitelist endpoints for OAuth Apr 27, 2016
@figureone
Copy link
Member

@figureone
Copy link
Member

I was under the impression that GET requests to the WP REST API were public, but that doesn't seem to be the case. Since REST calls already require another form of authentication, I'm fine whitelisting everything under /wp-json.

Let me do some research to see if there's an earlier place I can do the whitelisting.

Please let me know if find out the team working on wp-api decides to make any requests publicly accessible, I know it's a moving target until sometime later this year hopefully when it's finalized.

@figureone
Copy link
Member

figureone commented Apr 30, 2016

Hm, I think we'll have to get more creative on this one. I tested, and GET requests to /wp-json are public.

Example:
http://example.com/wp-json/wp/v2/posts/1
Will return the post data associated with post 1. This makes sense normally, because WordPress posts are available to the public. Authorizer can restrict access, so it makes sense that it will need to restrict access to REST calls as well.

Any thoughts?

@nurbs999
Copy link
Author

Public access for GET requests depends on the Authorizer setting for public access. If I restrict access to logged in users only, I also want the REST GET calls to be restricted, which is th case since 2.4.0.
Now comes the tricky part. If I use OAuth for authentication, I still need the endpoints /wp-json and /oauth/* to be public for the registration process to work.
Maybe this helps a little: http://code.tutsplus.com/tutorials/wp-rest-api-setting-up-and-using-oauth-10a-authentication--cms-24797

@figureone
Copy link
Member

Ok, I think I got it. You want Authorizer to restrict access to GET calls via the REST API just like it does with the rest of the site, but it doesn't need to restrict access to the rest of the REST API, since it's already protected by the authentication scheme configured (OAuth, basic/application, or cookie).
http://v2.wp-api.org/guide/authentication/

So we'll need to review the API endpoints to determine which should be whitelisted. It's probably more than just /wp-json and /oauth.

Additionally, I should probably be returning JSON when someone tries to access a restricted GET endpoint, instead of the default wp_error() behavior that Authorizer currently implements.

@figureone
Copy link
Member

Ok, I believe we have REST API integration working now: aeed2d3

Authorizer will now always allow access to the OAuth endpoint (usually /wp-json/oauth1), and it will always allow access to any REST endpoint for any non-GET request (POST, PUT, DELETE, etc.). The authentication scheme for the REST API (cookie-based, OAuth, or basic auth) will control that access.

Authorizer will monitor GET requests to REST endpoints; if the site is configured as private ("Only logged in users can see the site"), then anonymous users (not logged in) will get a JSON error message. Logged in users will get the JSON output from the REST API.

The remaining chore is to try to figure out if we can integrate OAuth on GET requests to any REST API endpoint. By default, the REST API doesn't do any authorization checks for view access. I'll have to think about this one some more, so let me know if you have any ideas.

I'll get this included in the next plugin update, and you can test and let me know if anything isn't working (or you can test now against the master branch if you're feeling brave).

@nurbs999
Copy link
Author

nurbs999 commented Jun 23, 2016

Thanks for the update!

My thoughts on GET requests are that it should depend on the Authorizer settings. If "Only logged in users can see the site" is set than any authorization should apply for view request. Whether it's an http request or a JSON request. So I would prefer OAuth authentication on GET request in that case.

@figureone
Copy link
Member

This is the way it should work now, assuming the OAuth plugin for rest-api hooks into the WordPress user system in the same way as regular logged in users. I don't have a rest-api + OAuth environment set up right now, so I'm hoping you can test to verify it works for each of the rest-api authentication methods (cookie, oauth, basic).

@figureone
Copy link
Member

With the last commit, I think we're good to go on all points related to rest-api now.
e635188

I've tested the oauth workflow (using the rest-api and oauth1 plugins, and using the demo wp-api-example-client app), and confirmed that, when a site is set to private with Authorizer:

  • Discovery and oauth authentication requests to the REST endpoints work;
  • GET requests to a REST endpoint from unauthorized clients will return a JSON error;
  • GET requests from an authenticated user (either via oauth1 or cookie) will work;
  • Other requests (POST, HEAD) to REST endpoints will be ignored by Authorizer and authorization will be handled by rest-api.

These updates will make it into the next official version, which has been a long time coming. If you want them now, feel free to check out master and test.

@figureone
Copy link
Member

New version is out with this feature. Please let me know if you find any problems.
https://wordpress.org/plugins/authorizer/changelog/

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

2 participants