1个不稳定版本
0.1.0 | 2021年8月12日 |
---|
#444 在 认证
每月49次下载
44KB
456 代码行
tide-openidconnect
Tide的OpenID Connect中间件。
此crate提供中间件,可用于验证Tide应用程序的用户,可选地阻止未认证的请求访问某些路由。中间件不与用户凭据交互、存储或以其他方式处理用户凭据,而是依赖于OpenID Connect身份提供者进行用户认证。
身份提供者管理用户凭据,可能允许或不允许用户注册,并使用OAuth 2.0框架允许应用程序请求令牌。这些令牌然后可用于识别用户并授予他们对应用程序的访问权限。此crate提供了与身份提供者集成、执行令牌交换并将结果提供给Tide请求所需的功能。
例如,Auth0、Azure和Google是几个兼容OpenID Connect的身份提供者示例。
用法
将其添加到您的Cargo.toml
[dependencies]
tide-openidconnect = "0.1"
示例
use tide_openidconnect::{OpenIdConnectRequestExt, OpenIdConnectRouteExt};
#[async_std::main]
async fn main() -> tide::Result<()> {
let mut app = tide::new();
// OpenID Connect middleware *requires* session storage. Note that the
// cookies must be configured with `SameSite::Lax`.
app.with(
tide::sessions::SessionMiddleware::new(
tide::sessions::MemoryStore::new(),
b"don't actually use a hardcoded secret",
)
.with_same_site_policy(tide::http::cookies::SameSite::Lax),
);
// Initialize the OpenID Connect middleware; normally all of these
// configuration values would come from an environment-specific config
// file, and in fact that is why they are in their own struct (so that
// you can deserialize that struct from a file or environment variables).
app.with(
tide_openidconnect::OpenIdConnectMiddleware::new(
&tide_openidconnect::Config {
issuer_url: tide_openidconnect::IssuerUrl::new("https://your-tenant-name.us.auth0.com/".to_string()).unwrap(),
client_id: tide_openidconnect::ClientId::new("app-id-goes-here".to_string()),
client_secret: tide_openidconnect::ClientSecret::new("app-secret-goes-here".to_string()),
redirect_url: tide_openidconnect::RedirectUrl::new("http://your.cool.site/callback".to_string()).unwrap(),
idp_logout_url: None,
}
)
.await,
);
// Define a basic Tide route, but protect it with the middleware's
// `.authenticated()` route extension.
app.at("/").authenticated().get(|req: tide::Request<()>| async move {
Ok(format!(
"If you got this far, then the request is authenticated, and your user id is {:?}",
req.user_id()
))
});
app.listen("127.0.0.1:8000").await?;
Ok(())
}
在示例目录中查看更多示例。
登录流程
此中间件使用OAuth 2.0 授权码授予流程,这是一种基于重定向的流程:用户导航到登录路径(默认为/login
),然后中间件将浏览器重定向到身份提供者的授权端点。登录成功后,浏览器将被重定向到登录着陆页。
启动此过程的一种方法是使用is_authenticated()
请求扩展检查每个请求的认证状态,然后在请求未认证时显示登录路径的链接。
此包还提供了一个路由扩展,可以将未认证的请求强制导向登录过程。这是一种保护路由而无需逐个检查请求认证状态的方法。使用此路由扩展,未认证的请求将自动将浏览器重定向到登录路径,然后到身份提供者。
请注意,使用此路由扩展存在一些注意事项;有关更多信息,请参阅OpenIdConnectRouteExt
文档。
注销流程
用户可以通过导航到注销路径(默认为/logout
)来注销应用程序;这将销毁他们的整个Tide会话并将他们返回到注销登录路径。您可以选择性地配置注销过程,只清除会话中的认证状态,保留会话数据的其余部分。
某些身份提供者还支持清除与提供者相关的浏览器状态,您的应用程序可以通过在配置中间件时设置idp_logout_url
来可选地启用该功能。
Tide路由拦截
此中间件使用三个路由来执行OAuth 2.0流程的功能。以下是这些路径的默认值,其中两个已在上面描述,所有这些路径都可以更改
/login
-- 启动OAuth 2.0登录过程。/logout
-- 销毁会话状态,并可选择清除身份提供者的状态。/callback
-- 身份提供者在成功登录后将浏览器发送到的“重定向URL”。
您不需要在Tide服务器中定义这些路由;中间件拦截对这些路径的GET
请求并自行处理。由于这种行为,这些路径在您的应用程序中不可用。
会话中间件要求
OpenID Connect中间件的主要输出是在Tide请求对象中添加有关请求认证状态的信息。Tide的会话中间件用于跟踪此状态,因此OpenID Connect中间件需要您在Tide应用程序中安装和配置会话中间件。如果会话中间件不存在,此中间件将在第一次登录请求时panic。
此外,由于OAuth 2.0流程中的各种HTTP重定向,需要将会话cookie配置为具有SameSite::Lax
安全策略。只要您的GET
(以及HEAD
、OPTIONS
和TRACE
)请求不更改状态或作为处理请求的一部分执行副作用操作,这就是安全的。保护“安全”(只读)的HTTP方法,而这些方法实际上并不是安全的,是使用默认会话cookie策略SameSite::Strict
的主要原因。针对使用cookie的未安全HTTP API的攻击称为跨站请求伪造(CSRF)攻击,而SameSite::Strict
是防御这些攻击的最简单方法之一,但只要您的GET
(以及HEAD
和...)请求仅用于返回数据,则SameSite::Lax
是安全的。
请注意,OpenID Connect 中间件在处理 OAuth 2.0 GET
请求时会修改认证状态,但同时也实现了多级 CSRF 防护措施,以保护这些 GET
请求免受恶意攻击。
行为准则
本项目遵循贡献者行为准则。这描述了所有贡献者应遵守的最基本行为规范。
许可
许可方式为以下之一
- Apache License,版本 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 https://opensource.org/licenses/MIT)
您可选择其中一种。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义,您有意提交的任何贡献,都将按上述方式双许可,不附加任何额外的条款或条件。
依赖
~29–42MB
~851K SLoC