security - 如何使用 OAuth Password Grant Type 获取授权码?
问题描述
我想使用 OAuth 在 Intranet 上授权用户(由username
,标识password
),但我不太了解如何使用 OAuth 来满足我的需求。
我主要关心的是防止backend
(客户端),收集用户的密码和前端,接收访问令牌。
如果我使用Password Grant Type,则只有前端可以收集用户凭据,但是由于此 Grant 方案没有重定向或授权代码,前端还将获得访问令牌,因此可能会被盗。
此外,使用此Password Grant Type,前端必须提供只有后端才知道的client_id和client_password。
在这种情况下如何使用 OAuth 和密码授予?
用例
我正在编写一个应接受来自 Active Directory 服务器的用户的 Intranet 平台。天真的解决方案是使用如下形式:
<form method="post">
<input type="text" name="username" required>
<input type="password" name="password" required>
<input type="submit" name="login">
</form>
因此,后端可以使用 Active Directory 服务器验证收到的凭据。但是,这是一个非常不安全的解决方案,因为后端可以收集用户的密码。在我编写应用程序时,这非常诱人:(
因此,我想设置不受我控制的第三方 OAuth 服务器,以便改用此表单:
<form action="http://oauth.company.com" method="post">
<input type="hidden" name="redirect" value="http://intranet.company.com">
<input type="hidden" name="grant_type" value="password">
<input type="hidden" name="client_id" value="badbeef">
<input type="text" name="username" required>
<input type="password" name="password" required>
<input type="submit" name="login">
</form>
使用此解决方案,只有前端会看到密码,但由于任何用户都可以检查源代码,因此这会阻止我尝试获取他们的密码,因为我会暴露太多。
使用OAuth 密码授予方案,我有两个问题:
- 前端必须
client_secret
知道. - 前端将收到访问令牌。
所以我想要两种解决方案:
- 前端获取一个授权码,然后将其传输到后端
- 授权服务器亲自通知后端访问令牌。
希望的身份验证流程
从前端,资源所有者输入发送到授权服务器的凭据,因此客户端不知道资源所有者凭据。
POST /oauth/token HTTP/1.1
Host: oauth.company.com
grant_type=password
&username=jdoe
&password=secret
&client_id=intranet-id
&state=123
&redirect=http://intranet.company.com/auth
授权服务器授予用户并将其发送回fontend:
HTTP/1.1 302 Found
Location: https://intranet.company.com/auth?code=g0ZGZmNjVmOWI&state=dkZmYxMzE2
然后后端使用接收到的代码请求访问令牌:
POST /oauth/token HTTP/1.1
Host: oauth.company.com
grant_type=????
&code=g0ZGZmNjVmOWI&state=dkZmYxMzE2
&client_id=intranet-id
&client_secret=intranet-secret
然后它收到:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
"scope":"create"
}
从这一点开始,后端将前端重定向到内网门户。
解决方案
资源所有者密码凭据授权是一个已弃用的流程,仅为迁移目的而定义。由于您列出的原因,它肯定不会与 Javascript 应用程序一起使用。在这种情况下使用隐式或授权代码授权,应用程序将(完整)浏览器重定向到身份提供者并且身份提供者可以在不涉及您的客户端的情况下对用户进行身份验证。
推荐阅读
- python-3.x - 如何在 Python 中获取 sas 数据集中的行数
- asp.net-mvc - 无法在 Visual Studio 2019 中执行任何脚手架
- swift - 如何使用 SwiftUI 制作单选列表
- vbscript - 如何使用 ASP 将参数传递给框架集
- c++ - 为什么我的删除功能总是出现分段错误
- google-cloud-platform - 获取“错误:无法释放未知资源。\n 在 SessionPool.release”
- python - 在大熊猫中读取 csv 时捕获异常
- c++ - Can std::cout print "NULL" instead of 0 when printing a null pointer?
- asp.net-core - 你能像使用 React 组件那样将子组件传递给 .NET Core ViewComponent 吗?
- django - 定义了一个 Form 类,但是 django 引发了异常,说它没有定义