Rust身份认证与访问控制库ory-client的使用,提供OAuth2、OIDC和权限管理功能

Rust身份认证与访问控制库ory-client的使用,提供OAuth2、OIDC和权限管理功能

简介

ory-client是一个Rust API客户端,用于访问所有公共和管理Ory API。管理API需要有效的个人访问令牌才能访问,而公共API主要用于浏览器场景。

安装

在Cargo.toml的[dependencies]下添加:

ory-client = { path = "./ory-client" }

或者直接运行:

cargo add ory-client

功能概述

ory-client提供了以下主要功能:

  1. OAuth2 - 完整的OAuth2客户端实现
  2. OIDC - OpenID Connect支持
  3. 权限管理 - 精细的访问控制功能
  4. 身份管理 - 用户身份创建、管理和验证

完整示例代码

以下是一个完整的示例,展示了如何使用ory-client集成OAuth2、OIDC、权限管理和身份管理功能:

use ory_client::apis::configuration::{Configuration, ApiKey};
use ory_client::apis::{oauth2_api, oidc_api, permission_api, identity_api};
use ory_client::models::{
    CreateOAuth2Client, RelationQuery, CreateIdentityBody, IdentityCredentialsPassword
};
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 1. 初始化配置
    let mut config = Configuration::new();
    config.base_path = "https://playground.projects.oryapis.com".to_string();
    config.api_key = Some(ApiKey {
        prefix: None,
        key: "YOUR_PERSONAL_ACCESS_TOKEN".to_string(),
    });

    // 2. OAuth2客户端管理
    println!("=== 创建OAuth2客户端 ===");
    let oauth_client = CreateOAuth2Client {
        client_name: Some("My Production Client".to_string()),
        redirect_uris: Some(vec!["https://myapp.com/callback".to_string()]),
        grant_types: Some(vec![
            "authorization_code".to_string(),
            "refresh_token".to_string(),
            "client_credentials".to_string()
        ]),
        ..Default::default()
    };

    let created_client = oauth2_api::create_o_auth2_client(&config, Some(oauth_client))
        .await?;
    println!("OAuth2客户端创建成功: {:?}", created_client);

    // 3. OIDC配置发现
    println!("\n=== 获取OIDC配置 ===");
    let oidc_config = oidc_api::discover_oidc_configuration(&config).await?;
    println!("OIDC配置: {:?}", oidc_config);

    // 4. 权限检查
    println!("\n=== 检查权限 ===");
    let permission_query = RelationQuery {
        namespace: Some("documents".to_string()),
        object: Some("/finance/report.pdf".to_string()),
        relation: Some("read".to_string()),
        subject_id: Some("finance-team".to_string()),
        ..Default::default()
    };

    let permission_result = permission_api::check_permission_or_error(&config, permission_query)
        .await?;
    println!("权限检查结果: {:?}", permission_result);

    // 5. 身份管理
    println!("\n=== 创建用户身份 ===");
    let new_identity = CreateIdentityBody {
        schema_id: Some("default".to_string()),
        traits: serde_json::json!({
            "email": "jane.doe@example.com",
            "name": {
                "first": "Jane",
                "last": "Doe"
            },
            "department": "engineering"
        }),
        credentials: Some(IdentityCredentialsPassword {
            password: Some("SecurePassword123!".to_string()),
        }),
        ..Default::default()
    };

    let created_identity = identity_api::create_identity(&config, Some(new_identity))
        .await?;
    println!("用户身份创建成功: {:?}", created_identity);

    Ok(())
}

代码说明

  1. 配置初始化:

    • 设置API基础路径
    • 配置个人访问令牌
  2. OAuth2客户端管理:

    • 创建OAuth2客户端
    • 配置重定向URI和授权类型
  3. OIDC发现:

    • 获取OIDC配置端点信息
    • 可用于后续的OpenID Connect流程
  4. 权限检查:

    • 检查指定主体对资源的权限
    • 使用关系型权限模型
  5. 身份管理:

    • 创建新用户身份
    • 设置用户属性和密码凭证

获取文档

要访问生成的文档,请运行:

cargo doc --open

总结

ory-client为Rust开发者提供了完整的身份认证和访问控制解决方案,支持OAuth2、OIDC和精细的权限管理功能。通过上述完整示例,您可以快速集成这些功能到您的Rust应用中。


1 回复

Rust身份认证与访问控制库ory-client使用指南

概述

ory-client是一个Rust库,用于与Ory生态系统集成,提供OAuth 2.0、OpenID Connect(OIDC)和权限管理功能。它允许开发者轻松地将身份验证、授权和用户管理集成到Rust应用程序中。

主要功能

  • OAuth 2.0和OpenID Connect实现
  • 用户认证和会话管理
  • 细粒度的访问控制
  • 与Ory Hydra、Keto和Oathkeeper集成
  • 支持多种认证流程(授权码、客户端凭证等)

安装

在Cargo.toml中添加依赖:

[dependencies]
ory-client = "0.8.0"

基本使用方法

1. 初始化客户端

use ory_client::apis::configuration::Configuration;

let config = Configuration::new();
// 或者自定义配置
let custom_config = Configuration {
    base_path: "https://your-ory-instance.com".to_string(),
    ..Default::default()
};

2. OAuth2授权码流程示例

use ory_client::apis::oauth2_api;
use ory_client::models::{AcceptOAuth2ConsentRequest, OAuth2Client};

async fn oauth2_example() -> Result<(), Box<dyn std::error::Error>> {
    let config = Configuration::new();
    
    // 获取授权URL
    let auth_url = oauth2_api::get_oauth2_authorization_url(
        &config,
        "client_id",
        "code",
        "https://your-redirect-uri.com",
        Some("openid profile email"),
        Some("state_value"),
        None,
        None,
    ).await?;
    
    println!("Authorization URL: {}", auth_url);
    
    // 处理回调并获取token
    // 这里通常是用户被重定向回你的应用后处理
    // ...
    
    Ok(())
}

3. OpenID Connect用户信息获取

use ory_client::apis::oidc_api;

async fn get_user_info(config: &Configuration, access_token: &str) {
    let user_info = oidc_api::get_userinfo(&config, access_token).await;
    match user_info {
        Ok(info) => println!("User info: {:?}", info),
        Err(e) => eprintln!("Error getting user info: {}", e),
    }
}

4. 权限检查示例

use ory_client::apis::permission_api;
use ory_client::models::RelationQuery;

async fn check_permission(config: &Configuration) {
    let query = RelationQuery {
        namespace: "files".to_string(),
        object: "document1".to_string(),
        relation: "read".to_string(),
        subject_id: Some("user123".to_string()),
        ..Default::default()
    };
    
    let result = permission_api::check_permission(&config, &query).await;
    match result {
        Ok(response) => {
            if response.allowed {
                println!("Permission granted");
            } else {
                println!("Permission denied");
            }
        }
        Err(e) => eprintln!("Error checking permission: {}", e),
    }
}

高级用法

自定义HTTP客户端

use ory_client::apis::configuration::Configuration;
use reqwest::Client;

let http_client = Client::builder()
    .timeout(std::time::Duration::from_secs(30))
    .build()?;

let config = Configuration {
    client: http_client,
    base_path: "https://your-ory-instance.com".to_string(),
    ..Default::default()
};

错误处理

use ory_client::apis::Error;

async fn handle_auth() -> Result<(), Box<dyn std::error::Error>> {
    let config = Configuration::new();
    let result = oauth2_api::get_oauth2_authorization_url(
        &config,
        "client_id",
        "code",
        "https://your-redirect-uri.com",
        Some("openid profile email"),
        Some("state_value"),
        None,
        None,
    ).await;
    
    match result {
        Ok(url) => println!("Success: {}", url),
        Err(Error::ResponseError(re)) => {
            eprintln!("API error: {} - {}", re.status, re.content);
        }
        Err(e) => {
            eprintln!("Other error: {}", e);
        }
    }
    
    Ok(())
}

完整示例Demo

下面是一个完整的OAuth2授权码流程示例,包含获取授权URL和处理回调的完整流程:

use ory_client::apis::{configuration::Configuration, oauth2_api};
use ory_client::models::OAuth2TokenResponse;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化配置
    let config = Configuration {
        base_path: "https://your-ory-instance.com".to_string(),
        ..Default::default()
    };

    // 1. 获取授权URL
    let auth_url = oauth2_api::get_oauth2_authorization_url(
        &config,
        "your_client_id",
        "code",
        "https://your-redirect-uri.com/callback",
        Some("openid profile email"),
        Some("your_state_value"),
        None,
        None,
    ).await?;

    println!("请访问以下URL进行授权:\n{}", auth_url);

    // 2. 模拟用户授权后被重定向回你的应用
    // 通常在web应用中,这会由你的路由处理器处理
    let callback_url = "https://your-redirect-uri.com/callback?code=authorization_code&state=your_state_value";
    
    // 3. 从回调URL中提取授权码
    let query_params: HashMap<_, _> = url::Url::parse(callback_url)?
        .query_pairs()
        .into_owned()
        .collect();
    
    let auth_code = query_params.get("code").ok_or("Missing authorization code")?;
    let state = query_params.get("state").ok_or("Missing state")?;
    
    // 验证state参数防止CSRF攻击
    if state != "your_state_value" {
        return Err("Invalid state parameter".into());
    }

    // 4. 使用授权码获取token
    let token_response = oauth2_api::exchange_oauth2_token(
        &config,
        "authorization_code",
        "your_client_id",
        Some("your_client_secret"),
        None,
        Some(auth_code),
        Some("https://your-redirect-uri.com/callback"),
        None,
        None,
        None,
    ).await?;

    println!("Token响应: {:?}", token_response);

    // 5. 使用访问令牌获取用户信息
    if let Some(access_token) = token_response.access_token {
        let user_info = ory_client::apis::oidc_api::get_userinfo(&config, &access_token).await?;
        println!("用户信息: {:?}", user_info);
    }

    Ok(())
}

最佳实践

  1. 始终验证state参数以防止CSRF攻击
  2. 使用PKCE增强OAuth2安全性
  3. 缓存访问令牌并处理刷新令牌
  4. 在生产环境中使用HTTPS
  5. 定期检查权限缓存的有效性

注意事项

  • 确保正确配置Ory服务端(Hydra, Keto等)
  • 遵循OAuth2和OIDC的安全最佳实践
  • 在生产环境中使用适当的错误处理和日志记录

通过ory-client库,Rust开发者可以轻松集成强大的身份验证和授权功能到他们的应用程序中,同时保持Rust的安全性和性能优势。

回到顶部