如何使用OAuth密码授予类型获取授权码?

时间:2018-07-21 22:54:24

标签: security oauth

我想使用OAuth对Intranet上的用户(由usernamepassword标识)进行授权,但是我不太了解如何使用OAuth满足我的需求。

我主要关心的是防止backend(客户端)收集用户的密码和前端,以接收访问令牌。

如果我使用密码授予类型,则只有前端可以收集用户凭据,但是因为没有重定向,也没有授权码对于此Grant计划,前端也将获得访问令牌,因此可以将其窃取。

此外,使用此 Password Grant Type (密码授予类型),前端必须同时提供 client_id client_password 仅由后端知道。

在这种情况下如何将OAuth与 Password Grant 一起使用?

用例

我正在编写一个内部网平台,该平台应接受来自Active Directory服务器的用户。天真的解决方案是使用如下形式:

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

使用此解决方案,只有 frontend 会看到密码,但是由于任何用户都可以检查源代码,因此这会阻止我尝试获取他们的密码,因为这样会暴露太多。

使用 OAuth 密码授予方案,我有两个问题:

  • 前端必须了解client_secret
  • 前端将收到访问令牌

所以我想要任何一种解决方案:

  1. 前端得到一个授权码,然后将其传输到后端
  2. 授权服务器亲自将访问令牌通知后端

希望的身份验证流程

资源所有者前端输入其凭据,该凭据将发送到授权服务器,从而发送到客户端 em>不知道资源所有者凭据。

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

然后,后端使用接收到的 code 请求访问令牌

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"
}

从这一点开始,后端 frontend 重定向到Intranet门户。

1 个答案:

答案 0 :(得分:1)

“资源所有者密码凭据”授予是不推荐使用的流,仅出于迁移目的而定义。由于您列出的原因,它肯定不能与Javascript应用程序一起使用。如果应用程序将(完整的)浏览器重定向到身份提供者,并且身份提供者可以在不涉及您的客户端的情况下对用户进行身份验证,则使用“隐式”或“授权代码”授予。