经过身份验证的 REST 请求是否始终意味着数据库请求?
我正在使用 RESTeasy 框架来开发我的 Web 服务。我已成功设置 BASIC 身份验证,并且现在工作正常。当然,我确实计划在此基础上使用 SSL。
该过程很简单(如果您不知道这是什么,请阅读有关 HTTP 基本身份验证的内容是关于):
- 每个请求都会被分析请求标头的方法拦截。
- 该标头被解码并提取用户名和密码。
- 然后该方法查询数据库以检查用户名和密码是否匹配。
- 如果它们与请求继续匹配,如果不匹配,则返回 401 代码。
使用这种方法,由于 REST(以及 HTTP 本身)的无状态性质,每个请求都意味着对数据库的请求。
我的问题是:是否可以不对每个经过身份验证的请求查询数据库?
可能的提示:使用 cookie 的某种机制?
这个问题在技术上是不可知的。
顺便说一句:
我真的觉得关于 REST 身份验证问题的信息很少。这只是 OAuth、OAuth、OAuth...如果我们不想验证第 3 方应用程序,则信息分散在各处,并且没有任何具体示例,例如使用 OAuth。 如果您对 REST Web 服务中的身份验证有任何好的建议,我很想听听。
谢谢。
I'm using RESTeasy framework to develop my web service. I've managed to set up BASIC authentication, and it is working properly now. Of course, I do plan to use SSL on top of this.
The process is simple (and please read something about HTTP basic Auth if you don't know what this is about):
- Every request is intercepted by a method which analyzes the request header.
- This header is decoded and the username and password are extracted.
- The method then queries the database to check if the username and password match.
- If they match the request proceeds, if they don't, a 401 code is returned.
With this approach, every request implies a request to the database, due to the stateless nature of REST (and HTTP itself).
My question is: Is it possible to don't query the database on every authenticated request?
Possible hints: Some mechanism using cookies?
This question is technologically agnostic.
Just as a side note:
I really feel that there is very little information on this REST authentication matter. It's just OAuth, OAuth, OAuth... If we don't want to authenticate 3rd party applications, information is scattered everywhere and there aren't any concrete examples, like there are using OAuth.
If you have any good advises regarding Authentication in REST WebServices, I would love to hear them.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
有多种方法可以使用 cookie 实现“Auth Ticket”(google 一下,您可能会找到一些非 OAuth 引用),因此并非每个请求都需要数据库查询。然而,这些通常涉及加密密钥。
我不相信最佳实践应该是将加密密钥存储在源文件中(但这就是教程通常实现它的方式),因此您可能会涉及某种磁盘访问(通过属性文件、密钥库等),即使您不查询数据库。
正如 Perception 所说,将 cookie(状态)添加到无状态系统设计中是一种作弊行为。
There are various ways to implement an "Auth Ticket" (google that and you'll probably find some non-OAuth references) with cookies so that not every request requires a database query. However, these usually involve a crypto key.
I'm not convinced that best practices should be to store the crypto key in the source files (but this is how tutorials usually implement it), so you might involve some sort of disk access (via properties file, keystore, etc) even if you don't query a database.
As Perception states, adding cookies (state) to a stateless system design is sort of cheating.
使用 memcached 作为数据库的中间层。检查凭据是否已缓存,如果它们继续请求,如果未缓存,则从数据库中提取它们并验证凭据。如果凭据匹配,则缓存它们以供将来请求并继续当前请求。
请记住,访问 memchaced 必须与访问数据库一样安全,因为数据库中存储了密码。这是许多网站使用 OAuth 的原因之一,尤其是 OAuth 2,您可以在其中分发短期访问令牌和长期刷新令牌,后者将在需要时获取新的访问令牌。
Use something like memcached as an intermediate to your database. Check if credentials are cached, if they are continue with the request, if they are not cached, pull them from the database and verify the credentials. If the credentials match cache them for future requests and continue with the current one.
Keep in mind that access to memchaced must be as secure as access to your database since it hass passwords stored in it. This is one of the reasons So many sites are using OAuth, especially OAuth 2 where you hand out a short lived access token and a long lived refresh token that will get a new access token when needed.
欢迎来到代表性国家转移安全的世界!您知道,我向 Roy Fielding 发送了一条消息,询问如何创建一个真正安全且真正 RESTful 的服务。他还没有回我。
您的两个选择实际上是基本身份验证(希望使用 SSL,否则有什么意义)或 OAuth。对于我目前参与的所有解决方案,我们都使用 OAuth。虽然它使测试变得复杂,但它非常安全,并且允许我们从我们的服务中创建可外部化的 API。
我建议不要使用 cookie 来存储会话信息。这不仅违反了 REST 的精神,而且还使您的应用程序容易遭受会话劫持。为了加快速度,您可以做的一件事是维护一个包含用户信息的良好二级缓存,这样您的查询实际上不会针对每个传入请求访问数据库。这可以显着提高速度。此策略对于基本身份验证和 Oauth 同样有效。
Welcome to the world of Representational State Tranfer Security! You know, I sent a message to Roy Fielding asking how you could create a truly RESTful service that was also secure. He hasn't gotten back to me yet.
Your two options really are Basic Auth (hopefully using SSL, or what's the point), or OAuth. For all the solutions I am currently involved with we are using OAuth. While it complicates testing it is very secure and allows us to create externalizable API's out of our services.
I advice against using cookies to store session information. Not only does this violate the spirit of REST, but it also opens up your application to session hijacking. One thing that you can do to speed things up is maintain a good second level cache with user information, so that your queries don't actually hit the DB for every incoming requests. This can give a significant speed boost. This tactic works equally well for both basic auth and Oauth.
如果您与 AppEninge 的 UserService 集成(以及 Google 帐户),那么您可以防止任何查询。 RESTlet 有一个框架附带的超级优雅的验证器:
If you integrate with the UserService of AppEninge (and as such with Google accounts), then you can prevent any queries. RESTlet has a super elegant authenticator that comes with the framework :
答案最终是缓存。
在我的特定情况下,我使用 RESTeasy 作为 REST 框架,使用 Google App Engine 作为应用程序服务器。不难发现 GAE 支持 内存缓存。
如果您使用 Objectify(您确实应该这样做;它非常棒),那就更简单了。只需使用 @Cached 注释您的实体类。 此处对此过程进行了说明。
Objectify 支持会话对象中的另一种缓存。换句话说,只要实例化了您的 Objectify 对象,即使不使用 memcache,它也可以提供您的对象(这很好,因为在 GAE 中存在使用 memcache 的配额,尽管它们比数据存储区便宜)。我强烈建议您阅读 Objectify wiki 中的良好实践。
最后一点,我将考虑使用摘要式身份验证而不是基本。看起来安全多了。密码永远不会通过网络传输这一事实确实让我松了一口气。
我希望这个问题对某人和那些帮助我的人有用:谢谢。 :)
The answer ended up to be cache.
In my particular case I was using RESTeasy as a REST framework and Google App Engine as the Application Server. It wasn't hard to find out that GAE has support to memcache.
If you're using Objectify (you really should; it's awesome), it's even easier. Just annotate your entity classes with @Cached. This procedure is illustrated here.
Objectify supports another kind of cache in a session Object. In other words, as long your Objectify object is instantiated, it can provide your objects even without using memcache (This is good because in GAE there quotas for using memcache, although they are cheaper than the datastore ones). I strongly advise you to read Objectify's good practices in their wiki.
As a final note, I'll consider using Digest authentication instead of Basic. It seems much more secure. The fact that the password never travels through the network really reliefs me.
I hope that this SO question was useful to someone and for those who helped me: thank you. :)