17个版本 (重大更新)
0.14.0 | 2024年1月22日 |
---|---|
0.13.0 | 2023年11月21日 |
0.12.0 | 2023年10月14日 |
0.10.1 | 2023年7月11日 |
0.8.1 | 2023年3月16日 |
在认证类别中排名#73
每月下载量9,370
在 3 crates中使用
81KB
2K SLoC
jwt-authorizer
JWT授权层,用于Axum和Tonic。
功能
- JWT令牌验证(Bearer)
- 算法:ECDSA、RSA、EdDSA、HMAC
- 支持JWKS端点
- 可配置刷新
- OpenId Connect发现
- 验证
- exp, nbf, iss, aud
- 声明提取
- 声明检查器
- 跟踪支持(错误日志)
- tonic支持
- 多个授权者
使用示例
# use jwt_authorizer::{AuthError, Authorizer, JwtAuthorizer, JwtClaims, RegisteredClaims, IntoLayer};
# use axum::{routing::get, Router};
# use serde::Deserialize;
# use tokio::net::TcpListener;
# async {
// let's create an authorizer builder from a JWKS Endpoint
// (a serializable struct can be used to represent jwt claims, JwtAuthorizer<RegisteredClaims> is the default)
let auth: Authorizer =
JwtAuthorizer::from_jwks_url("https://127.0.0.1:3000/oidc/jwks").build().await.unwrap();
// adding the authorization layer
let app = Router::new().route("/protected", get(protected))
.layer(auth.into_layer());
// proteced handler with user injection (mapping some jwt claims)
async fn protected(JwtClaims(user): JwtClaims<RegisteredClaims>) -> Result<String, AuthError> {
// Send the protected data to the user
Ok(format!("Welcome: {:?}", user.sub))
}
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app.into_make_service()).await.expect("server failed");
# };
多个授权者
可以使用多个授权者构建一个层(为[Authorizer<C>; N]和
Vec<Authorizer<C>>
实现了IntoLayer
)。授权者将按顺序应用,直到其中一个验证令牌。如果没有授权者验证,则请求将被拒绝。
验证
验证配置对象。
如果没有提供验证配置,将应用默认值。
# use jwt_authorizer::{JwtAuthorizer, Validation};
# use serde_json::Value;
let validation = Validation::new()
.iss(&["https://issuer1", "https://issuer2"])
.aud(&["audience1"])
.nbf(true)
.leeway(20);
let jwt_auth: JwtAuthorizer<Value> = JwtAuthorizer::from_oidc("https://accounts.google.com")
.validation(validation);
ClaimsChecker
可以向授权者添加一个检查函数(将反序列化的声明映射到布尔值)。
检查失败将导致403错误(WWW-Authenticate: Bearer error="insufficient_scope")。
示例
use jwt_authorizer::{JwtAuthorizer};
use serde::Deserialize;
// Authorized entity, struct deserializable from JWT claims
#[derive(Debug, Deserialize, Clone)]
struct User {
sub: String,
}
let authorizer = JwtAuthorizer::from_rsa_pem("../config/jwtRS256.key.pub")
.check(
|claims: &User| claims.sub.contains('@') // must be an email
);
JWKS刷新
默认情况下,当请求令牌使用商店中不存在的关键字(jwt头部的kid字段)签名时,会重新加载jwks关键字(两次重新加载之间的最小间隔默认为10秒,可配置)。
JwtAuthorizer::no_refresh()
配置一个唯一的jwks关键字刷新JwtAuthorizer::refresh(refresh_configuration)
允许定义更细致的 jwks 刷新配置,更多详情请查看Refresh
结构体的文档。
依赖项
~13–30MB
~513K SLoC