在Play框架和OAuth2上保护REST API

43

我正在使用 Play 2.0Scala 开发一个应用程序,它公开了一些 REST API。这些 API 将由不同的应用程序,包括 Web、移动和桌面应用程序使用,因此 OAuth 协议(OAuth2)似乎最合适。

另外,我最初会使用 Facebook 等外部 OAuth 提供者。

我的问题是:授权每个 REST 调用的确切流程是什么?对于每个调用,服务器端应该期望什么,并且我应该与外部提供者检查什么?

在 OAuth1 中,我知道客户端会随所有签名请求发送令牌,但我认为 OAuth2 不是这样,如果令牌没有被签名,则不被信任,因此我不认为这是正确的流程。

7个回答

17

6
我认为问题是如何使用Play框架开发自己的Oauth2提供者,而不是集成第三方Oauth2提供者。 - Jeff Wu
@JeffWu,你说得对。我想实现一个通用的Oauth2流程来进行服务授权,这样我就可以避免使用非“标准”的第三方库。最终目的是开发自己的Oauth2提供者。 - Marco

16
我将Apache Amber移植到了Play2 Scala,这是链接:https://github.com/cleanyong/oauth2play2scala 移植Apache Amber的原因如下:
  1. 它经过测试
  2. 比自制的更好
  3. 它适合Play2 Scala API
  4. 易于使用
  5. 不会有太多干扰
如果您想在您的网站上设置oauth2服务器,可以尝试使用我的移植版本。它附带了文档。

7
基本上,标准流程如下:
  1. 每次请求时,检查cookie(Play!方言中的“session”)是否包含id
  2. 如果没有,则要求用户使用提供者(Facebook或其他)进行身份验证
  3. 如果通过,提供者将返回一个ID,在您的持久性系统(注册)和当前cookie /会话中保存此ID
  4. 在下一次请求时,检查ID是否存在于cookie / session中,并且与您的持久性系统中的现有用户相对应
  5. 要“注销”,只需清除cookie /会话
如果您需要更多详细信息,请询问 :-)

4

OAuth是一种授权协议,如果您正在寻找身份验证解决方案,可能不适用于此。

您的问题表明API的消费者将是各种应用程序。这导致了两种情况,

 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)

为了支持OAuth生态系统,您需要一个密钥管理系统。
需要做到以下两点:
  1. 为应用生成Key/Secret。
  2. 生成AccessToken/Refresh_token/authorization_code。
现在来看需要公开的终结点。
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&user_id=user@YourAPIService.com&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

否则,最简单/最稳健的解决方案是使用http://apigee.com现有的OAuth生态系统。

1

我自己没有尝试过,但是如何使用tuxdna模块呢? 在github存储库中,它说:

使用Play!2.0框架的OAuth2服务器

希望这可以帮助到你


0

0

我曾经遇到过同样的问题,我的解决方法(虽然不是最好的)是将REST服务器的方法放在"@Security.Authenticated(Secure.class)"中,并使用一个会话cookie(也在后端的哈希表中注册)。该会话cookie是用户登录后生成的。

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... 

}

并且

package controllers;

import ...;

public class Secure extends Security.Authenticator {

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

希望这能有所帮助。

这是应该在评论中出现的回复类型,而不是答案。你应该回答一些问题并获得赞同和声望。这相当有趣。 - HalR
好的,我尝试修改答案...谢谢 - user9869932

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接