RESTful用户认证服务

发布于 2024-08-16 17:29:09 字数 928 浏览 5 评论 0 原文

大家好,这似乎已经被经常讨论,但我想就使用 RESTful 服务进行身份验证提出一个简单的、淡化的问题。场景如下:

  • 有一个系统容纳应用程序的注册用户。系统公开了一个 RESTful API 来访问这些用户。
  • 有一个带有登录表单的前端应用程序。该应用程序可以是内部的,也可以是外部的。
  • 前端应用程序需要使用用户系统中的数据来验证用户的身份。

现在的问题是如何根据用户系统中的数据对在客户端应用程序中输入凭据(用户名/密码)的用户进行身份验证,以确保安全和高性能?为了解决这个问题,假设客户端应用程序位于某种 Intranet 的内部,但应用程序不会驻留在同一台计算机上,并且只能通过服务进行通信。

我理解让应用程序成为“超媒体驱动”的想法,但我们应该能够提供过滤/搜索服务。例如,请考虑如下资源和 API:

  • http://example.com/users
    • GET - 检索所有用户(分页、超媒体驱动)
    • POST - 创建新用户
    • 不支持放置/删除
  • http://example.com/users/[id]
    • GET - 返回 id = {id} 的用户的完整表示
    • PUT - 更新用户,接受任何预定义的媒体类型
    • DELETE - 删除用户(具有适当的授权)
    • 不支持 POST

根据上述内容,我的想法客户端应用程序将在用户列表上获取 GET,并按用户名进行过滤。该服务将散列密码和盐返回给客户端,客户端将执行身份验证。

想法?

Hey folks, this seems to have been discussion fairly often but I want to make a simple, watered down question around doing authentication with RESTful services. The scenario is as follows:

  • There is a system that houses registered users for an application. The system exposes a RESTful API for accessing these users.
  • There is a front-end application that has a login form. The application can either be internal, or external.
  • The front-end application needs to use the data in the User system to authenticate a user.

The question now is how to authenticate a user whose credentials (username/password) are entered in the client application against the data in the User system such that it is secure and performant? For the sake of this question, suppose the client application is internal to some sort of Intranet but the applications will not reside on the same machine and may only communicate through the service.

I understand the idea of having the application being "hypermedia driven" but we should be able to provide filtering/searching services. For example, consider the resources and API as below:

  • http://example.com/users
    • GET - retrieves all users (paged, hypermedia driven)
    • POST - creates new user
    • PUT/DELETE not supported
  • http://example.com/users/[id]
    • GET - returns a full representation of a user with id = {id}
    • PUT - updates user, takes in any predefined media type
    • DELETE - deletes the user (with appropriate authorization)
    • POST not supported

Based on the above, my idea would be have the client application GET on the user listing, filtering by username. The service will return the hashed password and salt to the client, the client will perform the authentication.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谁人与我共长歌 2024-08-23 17:29:09

如果我正确理解您的问题,您正在寻求实现一个处理身份验证的通用服务,以便您可以将其重新用于不同的应用程序。

我建议您看一下OAuth,它正是针对这个问题域而构建的。

If I understand your question correctly, you are looking to implement a generic service that will handle authentication, so that you can re-use it for different applications.

I suggest you take a look at OAuth which has been built for precisely this problem domain.

不离久伴 2024-08-23 17:29:09

将用户名和盐传回是不必要的,并且存在真正的安全风险。

也许您可以考虑这种方法:

让客户端通过 基本身份验证

服务器获取用户名的加密密码以及盐

服务器使用某种加密方法(使用盐)对给定密码进行加密辅助算法(Ruby 代码如下):

def User.authenticate(login, password)
    ok = false

    user = User.find_by_login(login)

    if user
        #
        #   user contains the salt, it isn't passed from the client
        #  
        expected_password = hash_password(password, user.salt)

        ok = (user.password == expected_password)
    end

    return ok
end

有多个地方可以使用这种方法,但我喜欢在 Rack 中进行。

最后一点,这一切都在 HTTPS 连接上完成

Passing the username and the salt back is unnecessary and a real security risk.

Perhaps you could consider this approach:

Have the client pass the username and password to the server via Basic Authentication

The server fetches the encrypted password for the username along wiht the salt

The server encrypts the given password using some encryption method, using the salt to assist the algorithm (Ruby code follows):

def User.authenticate(login, password)
    ok = false

    user = User.find_by_login(login)

    if user
        #
        #   user contains the salt, it isn't passed from the client
        #  
        expected_password = hash_password(password, user.salt)

        ok = (user.password == expected_password)
    end

    return ok
end

There are multiple places to use this kind of approach but I like to do it in Rack.

Last point, do it all on a HTTPS connection

怼怹恏 2024-08-23 17:29:09

Stormpath

Stormpath 公司致力于为开发者提供用户登录管理 API 和服务。他们使用 REST JSON 方法。

还有一些其他公司似乎也涉足身份验证即服务这一新领域,但据我所知,Stormpath 是唯一一家致力于此领域的公司。

Stormpath

Stormpath company dedicated to providing a user login management API and service for developers. They use a REST JSON approach.

There are some other companies that seem to dabble in this new area of authentication-as-a-service, but Stormpath is the only one I know of that is dedicated to it.

耳钉梦 2024-08-23 17:29:09

首先,您不希望客户端执行身份验证,因为这样编写一个闯入您的服务的客户端就很简单了。

相反,只需使用 HTTP BasicHTTP 摘要

请注意,如果您使用 Java,则 Restlet 框架提供称为 Guards 的拦截器,它支持这些拦截器和其他拦截器机制。我强烈推荐雷斯特莱特。

First, you don't want the client to perform the authentication, as it then would be trivial to write a client that breaks into your service.

Instead, just use an authentication mechanism like HTTP Basic or HTTP Digest.

Note that if you're using Java, the Restlet framework provides interceptors, called Guards, which support these and other mechanisms. I highly recommend Restlet.

坏尐絯℡ 2024-08-23 17:29:09

Mozilla 角色

自从这个问题发布以来,Mozilla 基金会Firefox浏览器)解决了简单用户认证的问题。他们的解决方案是 Mozilla Persona,“网络登录系统”。旨在方便用户开发人员。用户的身份是电子邮件地址。请参阅维基百科文章

更新

Mozilla 基本上放弃了 Persona 的工作,但还没有完全被杀死 项目。

Mozilla Persona

Since this question was posted, the Mozilla Foundation (the maker of the Firefox browser) has taken on the problem of simple user authentication. Their solution is Mozilla Persona, "a sign-in system for the Web". Designed to be easy for users and for developers. The user's identity is an email address. See Wikipedia article.

Update

Mozilla has basically given up work on Persona but not quite killed the project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文