如何在Restful API中隔离数据

如何在Restful API中隔离数据,rest,restful-authentication,restful-architecture,restful-url,Rest,Restful Authentication,Restful Architecture,Restful Url,有一些restful API,如下所示: api/v1/billing/invoices/{invoiceNumber} api/v1/billing/transactions/{transactionNumber} 而且,每个发票或交易都属于一个特定的账户 在实现restful API时,我们必须满足以下要求:每个帐户只能查看自己的发票或交易。 我们应该如何在restful API中隔离数据 当然,我们可以将账号传递给api,例如: api/v1//billing/invoices/{inv

有一些restful API,如下所示:

api/v1/billing/invoices/{invoiceNumber}
api/v1/billing/transactions/{transactionNumber}
而且,每个发票或交易都属于一个特定的账户

在实现restful API时,我们必须满足以下要求:每个帐户只能查看自己的发票或交易。

我们应该如何在restful API中隔离数据

当然,我们可以将
账号
传递给api,例如:

api/v1//billing/invoices/{invoiceNumber}?accoutNumber=XXX
api/v1/billing/{accountNumber}/invoices/{invoiceNumber}
但是,
发票编号
能够唯一地标识资源。因此,我不希望问题变得复杂


还有别的办法解决这个问题吗?

你在这里混合了很多东西

这不是一个REST问题,这是一个安全问题。更准确地说,这是一个好消息

让我们简单一点:您有一个这样的URL

.../superSensitiveStuff/1
public class SuperSensitiveStuff {

    private String userId;
    private String secretStuff;
    ...
}
您想阻止“
1
”的所有者访问“
../superSensitiveStuff/2

据我所知,处理这个问题有三种方法:

  • 在请求URL中强制执行完整性。此策略并不适用于所有情况,它仅适用于客户端向服务器先前通信的资源发出请求的情况。在这种情况下,服务器可以像这样添加查询参数

    .../superSensitiveStuff/1
    
    public class SuperSensitiveStuff {
    
        private String userId;
        private String secretStuff;
        ...
    }
    
    ../superSensitiveStuff/1?sec=HMAC(…/superSensitiveStuff/1)

    其中HMAC是一个。如果缺少该参数,服务器将删除该请求,如果存在该请求,服务器将能够验证它是否正是授权的URL,因为HMAC值保证其完整性(有关其他信息,请点击上面的链接)

  • 使用不可预测的引用。这里的问题是,用户可以猜测另一个id。“嗯……我有资源编号1,让我检查资源编号2是否存在”。若你们删除序列,移动到长随机数,这是很难做到的。资源将成为

    ../superSensitiveStuff/195A23FR3548…32OT465

    这很好,因为它既有效又便宜

  • 利用混合RBAC-ABAC方法。RBAC代表基于角色的访问控制,这就是您正在使用的。第二个首字母缩略词的前导A代表属性。这意味着访问是基于用户角色和属性提供的。在本例中是userId,因为它必须经过身份验证才能访问私有资源。简言之,当用户请求特定的
    ../superSensitiveStuff
    资源时,当您拥有该资源的所有权信息时,将从存储库中加载该资源。例如,它可能是一个DB,您的超敏感的UFF java业务模型可能是这样的

    .../superSensitiveStuff/1
    
    public class SuperSensitiveStuff {
    
        private String userId;
        private String secretStuff;
        ...
    }
    
    现在,在控制器中,您可以执行以下操作

    String principal = getPrincipal(); //you request the logged userId
    SuperSensitiveStuff resource = myService.load(id); //you load the resource using the {id} in the request path
    if (resource.getUserId.equals(principal))
        return resource //200 ok, this is an authorized access
    else
        throw new EvilAttemptException() //401 unauthorized, cheater detected
    

  • 在这三个选项中,#3是唯一一个不是通过模糊来保证安全的选项。。。但是需要一个框架在它之上,我相信不管使用什么语言。HMAC和密码一样,都是通过隐蔽性实现安全的,也就是说,绝对不是#2可以通过模糊性被视为一种安全性,但如果随机性足够复杂,它就可以在企业场景中工作。HMAC的问题是它不能独立存在:。帐户的问题是攻击者创建一个获得HMAC的帐户,然后使用它自由访问其他帐户。#1和#2都是散列机制,虽然它们不太可能被猜到,但仍然不建议用于敏感数据……在处理安全问题时,您无法找到防止所有攻击场景的单一方法。这里的安全问题显然是通过猜测id来访问被禁止的资源。我想当然地认为API使用者将得到身份验证。如果您有其他防止不同攻击的策略,HMAC将以可靠的方式解决问题。当然,如果你把应用程序放在一个带有篡改证书的有毒wifi中的MITM场景中,它就会被破坏。但是它失败了,因为您放松了上下文约束。保护API的方法是特定于编程语言的,您使用的是什么语言?我使用c来编码