Securing REST API on Play framework and OAuth2
Asked Answered
L

7

42

I am developing an application with Play 2.0 and Scala that exposes some REST API. These APIs will be used by different applications, web, mobile or desktop, so the OAuth protocol (OAuth2) seems the most suitable.

Also I would initially use an external OAuth Provider such as Facebook.

My question is: what is the exact flow to authorize the individual REST call? What should I expect on the server side for each call and what I should check with the external provider?

With OAuth1 I knew that the client sent the token with all the signed request, but with Oauth2 I think not so, I imagine that if a token is not signed is not trusted and therefore I do not think this is the flow.

Larry answered 7/7, 2012 at 9:30 Comment(0)
W
17

You could use a module called SecureSocial.

https://github.com/jaliss/securesocial/

This one is quite refined and many people in Play community seem to be aware/using this module.

For authorization might be useful. https://github.com/schaloner/deadbolt-2/

For end to end scala stuff, https://github.com/t2v/play20-auth

Wardle answered 13/7, 2012 at 5:16 Comment(2)
I believe the question is for how to develop his own Oauth2 provider using the play framework, not integrate with third party Oauth2 providers.Accentuate
@JeffWu you are right. I would like to implement a general Oauth2 flow for service authorization, so I would be aware from using third party library if it is not "standard". The final destination is to develeop my own the Oauth2 provider.Larry
W
16

I ported Apache Amber to Play2 Scala, here is the link: https://github.com/cleanyong/oauth2play2scala

The reason to port Apache Amber is:

  1. it been tested
  2. better than home made
  3. it fit Play2 Scala API
  4. easy to use
  5. not intrusive

If you want to setup oauth2 server on your site, you can try use my port. It has document.

Weylin answered 10/8, 2013 at 2:50 Comment(0)
M
7

Basically, the standard flow is the following:

  1. on each request, check in the cookie ("session" in the Play! dialect) if it contains an id
  2. if not, ask the user to authenticate with the provider (Facebook or something else)
  3. If ok, the provider will return an id, save this id in your persistence system (registration), and in the current cookie/session
  4. on the next requests, check if the id exists in the cookie/session and corresponds to an existing user in your persistence system
  5. To "logout", just clear the cookie/session

If you want more details, just ask :-)

Merlenemerlin answered 15/7, 2012 at 12:21 Comment(0)
E
4

OAuth is an Authorization Protocol, so if you're looking at a Authentication Solution, this might not be the one.

You're question saying the consumer of the API will be various application. This lead to 2 scenarios,

 1. Where there is no end user involved (grant_type: client_credential)  
 2. Where end-user can consume these APIs on multiple Application (Owned by your Org) (grant_type: implicit/password)
 3. Where end-user can consume these APIs via third Party Applications.(authrization_code)

To support OAuth Eco-System you need a Key Management System. To,

  1. Generate Key/Secret for Apps.
  2. Generating AccessToken/Refresh_token/authorization_code

now coming to endpoint you would have to expose,

3-Legged OAuth
GET     /authorize  authorize{entry point/ initiate oauth}  
    Sample Call: http://YourAPIService.com/authorize?response_type=code&client_id=GG1IbStzH45ajx9cEeILqjFt&scope=READ&redirect_uri=www.google.com

    GET     /login  login (Call Page for login App, 302 redirected from /authorize)     
Sample Call: http://YourAPIService.com/v1/oauth20/login?response_type=code&client_id=GG1IbStzH45ajx9cEeILqjFt&scope=READ&redirect_uri=www.google.com

    POST    /dologin    consentPage     http://YourAPIService.com/dologin 
    Submit the credential, On success, render the application page 

    POST    /grantpermission    consentSubmission   http://YourAPIService.com/grantpermission
Permission has been granted/declined. Send a 302 to generate authorization_code 

    GET      /code          AuthorizationCode {To generate auth code}
    Sample Call: http://YourAPIService.com/code?client_id=GG1IbStzH45ajx9cEeILqjFt&response_type=code&[email protected]&redirect_uri=www.google.com

    POST    /token  GenerateAccessToken     http://YourAPIService.com/token 
Sample call: http://kohls-test.mars.apigee.net/v1/oauth20/token
Header: Authorization: Basic R0cxSWJTdHpINDVhang5Y0VlSUxxalFj its generated with apps Api Key & Secret.
Payload: 
grant_type=authorization_code&scope=x&redirect_uri=www.google.com&code=abc123

Otherwise simplest/robust solution would be, http://apigee.com

You can use existing OAuth ecosystem of Apigee.

Extravaganza answered 17/4, 2013 at 17:33 Comment(0)
S
1

I did not try it myself , but how about tuxdna module. As in the github repo it says:

OAuth2 Server using Play! 2.0 Framework

I hope this helps

Steepen answered 18/3, 2015 at 13:33 Comment(0)
F
0

I had the same problem, what I did ( I suppose It's not the best solution) was, to place the methods of the REST server, inside an "@Security.Authenticated(Secure.class)" , and, use a session cookie (which also was registered inside a Hash table in backend). The session cookie was generated after user sign-in

I post code:

package controllers;

import ...;

@Security.Authenticated(Secured.class)
public class ExampleController extends Controller {

    public static String currentUserEmail() {

 ... return json after checking that 'session("id")' exists in the loggedin users hash table... 

}

and

package controllers;

import ...;

public class Secure extends Security.Authenticator {

    @Override
    public String getUserId(Http.Context context) {
        return context.session().get("user_id");
    }
...
}

Hope this helps

Finnell answered 11/5, 2013 at 1:35 Comment(2)
This is the type of response that should be in a comments, not an answer. You should answer a few questions and get upvotes and get some rep on here. Its pretty engaging.Guarantor
Ok, It try modifying the answer... ThanksFinnell
P
0

You can try using this template for play that combines OAuth 2 provider with Deadbolt. The OAuth scope maps to the Deadbolt permission and role concept. It uses Redis to store access tokens, and they expire automatically after the time period you configure.

https://github.com/lglossman/scala-oauth2-deadbolt-redis

Patroon answered 12/7, 2016 at 19:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.