#oauth #proxy-server #oauth-token #cli #client #oauth2

nightly bin+lib olaf2

使用 OAuth2 的便捷 CLI 认证

3 个版本

0.0.3 2018年9月28日
0.0.2 2018年9月27日
0.0.1 2018年9月17日

#10 in #oauth-token

MIT 许可证

31KB
508

Olaf2 CLI 认证助手

这是一个为了使命令行应用程序使用第三方 OAuth 提供商方便地进行认证的非常简陋的实验性证明。

有关更详细的信息,请参阅文档

由于我们依赖于未发布的 github 版本的oauth2-rs,因此通过 crates 仍然无法完全工作。

此外,这是一个使用 edition 2018 的实验,因此事物可能无法正常工作。

不过,这里可能有一些有用的技术/概念可以被借鉴。


lib.rs:

Olaf2 是一个库,通过代理服务器使用 OAuth 2.0 方便地对命令行应用程序进行认证。

注意,OAuth 2.0 是一个 授权(authz)协议,而不是认证(authn)协议。OpenID Connect 被设计为 OAuth 2.0 之上的认证协议,但并未广泛部署。

Olaf2 通过授权代理服务器检索最终用户的身份信息来提供一种认证方式。例如,使用 Github 提供商,代理收到一个令牌,该令牌可用于与 Github API 一起使用,以恢复用户的 github 账户名称。

Olaf2 还可用于恢复本地访问资源的 OAuth 2.0 令牌。

大部分繁重的工作都由oauth2-rs crate 完成。

术语

“服务器”指的是 OAuth 2.0 授权服务器,它由 Olaf2 外部实现。我们提供了一些预配置的服务器以进行连接。

“代理”指的是 OAuth 2.0 客户端,它从服务器接收认证和授权。

“客户端”指的是通过运行协议进行认证的命令行应用程序。

“用户”指的是希望对 CLI 应用程序进行认证的 OAuth 2.0 资源所有者,并访问浏览器中的 URL。

用法

代理服务器

通过访问授权提供者网站来获取客户端 ID/密钥值。

配置代理,例如

# in proxy_config.toml
client_id = "deadbeefcafe1337"
client_secret = "somesecretvalue"
port = 8081
proxy_url = "https://127.0.0.1:8081/"
oauth_provider = "Github"
scopes = ["read:user", "user:email", "read:org"]
welcome_redirect = "https://127.0.0.1:8080/"

使用以下命令运行代理

   use olaf2::*;
use toml;

// the lazy way to load the config...
let toml = include_str!("proxy_config.toml");
let config: proxy::Config = toml::from_str(toml).unwrap();
proxy::run_with(config, |token| {
 	// This simple function prints the access token and
   	// returns it to the client
	let secret = token.secret().to_string();
	println!("Received token: {}", &secret);
	Ok(secret)
});

在此示例中,我们创建了一个会话令牌处理器,该处理器简单地打印访问令牌并将 String 返回给客户端。

在连接的另一端,我们需要告诉客户端接受 String

客户端

只需运行客户端即可

let secret = client::authenticate::<String>("http://127.0.0.1:8081");
println!("Secret: {}", secret); 

注意:代理服务器从闭包返回一个 String,因此我们为 authenticate 指定相同的类型参数。

详细信息

协议流程如下

  1. 客户端 在一个随机端口上启动本地 HTTP 服务器。向 proxy_url 发送 GET 请求,包括端口号和一个随机数。

代理 服务器返回 OAuth 2.0 授权请求 URL。

  1. 用户 访问此 URL(即 服务器)以授权请求。这包括将 URL 重定向回 代理

  2. 重定向请求应包含来自 OAuth 2.0 服务器 的授权码。

  3. 代理 使用授权码交换访问令牌。此令牌可以用来访问 服务器 资源(取决于请求的权限范围)。

  4. 代理 通过此访问确定 用户 的身份。然后 代理 通过提供包含最终会话令牌的 HTTP 页面(欢迎页面)来响应用户请求。

  5. 用户 浏览器向由 客户端 运行的本地 HTTP 服务器发出请求时,会捕获会话密钥,并且 客户端 可以继续在认证模式下运行。

图示

                       4. Exchange authz code from (3)
                       Use token to verify identity.
                       to get an access_token.
                       (e.g. GET /api/user?token=123)
              +------------------------------------------+
              ^                                          |
      +-------+--------+3. GET /oauth-cli/finish +-------+------+
      | OAuth 2.0      |   Response:             |  OAuth 2.0   |
      | Authz provider |   welcome page          |  Client      |
      | ("Server")     |      +-----------------^+  ("Proxy")   |
      +-------+--------+      |  5. Respond with +-------+------+
              ^               |     session token        ^
              |               |                          |
              +------+        |       +------------------+
2. In browser:       |        |       |       1. Get authz URL
Visit AuthURL        |        |       |       POST /oauth-cli/start
                     +--------+-------+-+
Response:            | CLI Application  |       Response: AuthURL
redirect-to          | ("Client"/"User")|
GET /oauth-cli/finish+---+----+---------+
?code=...&port=...       |    ^
                         |    |
                         +----+
                    6. GET localhost:<port>/
                    With some query values
                    e.g. new_secret=123


依赖关系

~52MB
~1M SLoC