mcpField
M
managing-tauri-plugin-permissions

managing-tauri-plugin-permissions

github.com/dchuk安全36156 次安装40 周前更新
代码仓库

关于 managing-tauri-plugin-permissions

面向 Tauri 应用开发者的安全配置技能,讲解如何按窗口和平台分配能力、配置插件权限及编写自定义插件权限。

主要功能

  1. 01按窗口与平台配置能力
  2. 02设置命令权限与路径范围
  3. 03创建自定义插件权限集
  4. 04自动生成允许与拒绝权限

适用场景

  1. 01限制不同窗口的系统访问
  2. 02为文件操作设置路径范围
  3. 03为自定义插件设计权限级别

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dchuk/claude-code-tauri-skills --skill managing-tauri-plugin-permissions

安装后在 Claude Code 中输入/managing-tauri-plugin-permissions确认已加载。

详细介绍

管理 Tauri 插件权限

Tauri 的 capability 和权限系统为桌面和移动应用提供细粒度的安全控制。本指南介绍如何为窗口和平台配置 capability、有效使用插件权限,以及编写自定义插件权限。

核心概念

Capabilities

Capabilities 是 JSON 配置文件,用于向特定窗口和平台分配权限。它们遵循最小权限原则。

位置:src-tauri/capabilities/

结构:

{
  "identifier": "capability-name",
  "description": "Human-readable purpose",
  "local": true,
  "windows": ["window-label"],
  "permissions": ["plugin:allow-action"],
  "platforms": ["linux", "windows", "macos", "android", "ios"]
}
权限级别

权限分为两个级别:

  • 命令:单项操作(例如,allow-write-text-file)
  • 作用域:基于路径的限制,用于定义可访问的文件/目录

特定平台的 Capabilities

指定目标平台

使用 platforms 字段将 capability 限定到特定操作系统:

{
  "identifier": "desktop-fs-access",
  "description": "Filesystem access for desktop platforms",
  "windows": ["main"],
  "permissions": ["fs:allow-home-read"],
  "platforms": ["linux", "windows", "macos"]
}

可用平台:linux、windows、macos、android、ios

仅限移动平台的 Capabilities
{
  "identifier": "mobile-camera",
  "description": "Camera access for mobile devices",
  "windows": ["main"],
  "permissions": ["camera:allow-capture"],
  "platforms": ["android", "ios"]
}

特定窗口的 Capabilities

配置多个窗口

在 tauri.conf.json 中定义窗口:

{
  "windows": [
    {
      "label": "main",
      "title": "Main Window",
      "width": 800,
      "height": 600
    },
    {
      "label": "settings",
      "title": "Settings",
      "width": 400,
      "height": 300
    }
  ]
}
为窗口分配 Capabilities

为每个窗口的需求创建单独的 capability 文件:

src-tauri/capabilities/main-window.json:

{
  "identifier": "main-window-capabilities",
  "description": "Full access for main window",
  "local": true,
  "windows": ["main"],
  "permissions": [
    "fs:allow-home-read",
    "fs:allow-home-write",
    "dialog:allow-open",
    "dialog:allow-save"
  ]
}

src-tauri/capabilities/settings-window.json:

{
  "identifier": "settings-window-capabilities",
  "description": "Limited access for settings window",
  "local": true,
  "windows": ["settings"],
  "permissions": [
    "fs:allow-app-read",
    "fs:allow-app-write"
  ]
}
在多个窗口间共享 Capabilities
{
  "identifier": "shared-dialog",
  "description": "Dialog access for multiple windows",
  "local": true,
  "windows": ["main", "settings"],
  "permissions": ["dialog:allow-ask", "dialog:allow-message"]
}

使用插件权限

默认权限集

每个插件都提供一个具有基础访问权限的 default 权限集。使用以下方式启用:

{
  "permissions": ["plugin-name:default"]
}
查找可用权限
  1. 官方插件:查看 Tauri 文档中的权限表
  2. 插件源码:查找 permissions/autogenerated 目录
  3. 社区插件:查看代码仓库或 crates.io 页面
权限标识符格式
plugin-name:permission-name

示例:

  • fs:allow-read
  • fs:allow-write-text-file
  • dialog:allow-open
  • shell:allow-spawn
使用作用域进行配置

将权限限制到特定路径:

{
  "identifier": "default",
  "description": "Main window capabilities",
  "windows": ["main"],
  "permissions": [
    "fs:allow-write-text-file",
    {
      "identifier": "fs:allow-read",
      "allow": [{ "path": "$HOME/Documents/**" }]
    },
    {
      "identifier": "fs:allow-write",
      "allow": [{ "path": "$APP/**" }]
    }
  ]
}
常见作用域变量
变量描述
$APP应用数据目录
$HOME用户主目录
$RESOURCE应用资源
$TEMP临时目录
$DESKTOP用户桌面
$DOCUMENT用户文档
$DOWNLOAD用户下载目录
拒绝权限

明确拒绝特定操作:

{
  "permissions": [
    "fs:default",
    "fs:deny-write-text-file"
  ]
}

编写自定义插件权限

插件结构

使用 Tauri CLI 创建插件:

cargo tauri plugin new my-plugin
cd tauri-plugin-my-plugin
实现命令

src/commands.rs:

use tauri::{command, AppHandle, Runtime};

#[command]
pub(crate) async fn read_data<R: Runtime>(
    key: String,
    app: AppHandle<R>,
) -> Result<String, String> {
    // Implementation
    Ok(format!("Data for key: {}", key))
}

#[command]
pub(crate) async fn write_data<R: Runtime>(
    key: String,
    value: String,
    app: AppHandle<R>,
) -> Result<(), String> {
    // Implementation
    Ok(())
}

#[command]
pub(crate) async fn delete_data<R: Runtime>(
    key: String,
    app: AppHandle<R>,
) -> Result<(), String> {
    // Implementation
    Ok(())
}
自动生成权限

src/build.rs:

const COMMANDS: &[&str] = &["read_data", "write_data", "delete_data"];

fn main() {
    tauri_plugin::Builder::new(COMMANDS)
        .global_api_script_path("./api-iife.js")
        .build();
}

这会生成:

  • allow-read-data / deny-read-data
  • allow-write-data / deny-write-data
  • allow-delete-data / deny-delete-data
定义默认权限

permissions/default.toml:

"$schema" = "schemas/schema.json"

[default]
description = "Default permissions for my-plugin. Allows read operations only."
permissions = ["allow-read-data"]
创建权限集

permissions/read-write.toml:

"$schema" = "schemas/schema.json"

[[set]]
identifier = "read-write"
description = "Allows both read and write operations"
permissions = ["allow-read-data", "allow-write-data"]

permissions/full-access.toml:

"$schema" = "schemas/schema.json"

[[set]]
identifier = "full-access"
description = "Allows all operations including delete"
permissions = ["allow-read-data", "allow-write-data", "allow-delete-data"]
注册命令

src/lib.rs:

use tauri::{
    plugin::{Builder, TauriPlugin},
    Manager, Runtime,
};

mod commands;

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("my-plugin")
        .invoke_handler(tauri::generate_handler![
            commands::read_data,
            commands::write_data,
            commands::delete_data,
        ])
        .build()
}
前端 JavaScript 绑定

guest-js/index.ts:

import { invoke } from '@tauri-apps/api/core';

export async function readData(key: string): Promise<string> {
  return await invoke('plugin:my-plugin|read_data', { key });
}

export async function writeData(key: string, value: string): Promise<void> {
  return await invoke('plugin:my-plugin|write_data', { key, value });
}

export async function deleteData(key: string): Promise<void> {
  return await invoke('plugin:my-plugin|delete_data', { key });
}
使用自定义插件权限

在应用的 capability 文件中:

{
  "identifier": "default",
  "windows": ["main"],
  "permissions": [
    "my-plugin:default",
    "my-plugin:read-write",
    "my-plugin:allow-delete-data"
  ]
}

完整示例:跨平台应用

src-tauri/capabilities/desktop.json:

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "desktop",
  "windows": ["main"],
  "platforms": ["linux", "windows", "macos"],
  "permissions": [
    "core:default",
    "fs:default",
    { "identifier": "fs:allow-read", "allow": [{ "path": "$HOME/Documents/**" }] },
    { "identifier": "fs:allow-write", "allow": [{ "path": "$APP/**" }] },
    "dialog:allow-open",
    "dialog:allow-save",
    "shell:allow-open"
  ]
}

src-tauri/capabilities/mobile.json:

{
  "identifier": "mobile",
  "windows": ["main"],
  "platforms": ["android", "ios"],
  "permissions": [
    "fs:allow-app-read",
    "fs:allow-app-write",
    "notification:default"
  ]
}

最佳实践

安全
  1. 最小权限原则:仅授予必需的权限
  2. 使用作用域:将文件访问限制到特定路径,而不是授予宽泛权限
  3. 按窗口分离:每个窗口只应拥有所需的权限
  4. 指定目标平台:避免在桌面端授予移动端权限,反之亦然
组织
  1. 按功能组织:按功能领域对 capabilities 分组
  2. 使用描述性标识符:明确说明 capability 的用途
  3. 记录权限:添加说明,解释每项权限的必要性
插件开发
  1. 最小化默认权限:默认权限集应具有限制性
  2. 创建权限集:提供分级访问权限(只读、读写、完全访问)
  3. 使用自动生成:让 Tauri 为命令生成允许/拒绝权限
  4. 测试权限:使用示例应用验证权限行为

故障排除

权限被拒绝错误

如果遇到权限错误:

  1. 检查能力文件语法(有效的 JSON)
  2. 确认窗口标签与配置相符
  3. 确认权限标识符正确
  4. 检查基于路径的操作是否需要作用域
未应用能力配置
  1. 确保能力文件位于 src-tauri/capabilities/
  2. 确认 windows 数组包含正确的窗口标签
  3. 检查 platforms 是否包含目标操作系统
  4. 更改能力配置后重新构建应用程序

参考资料

评论

支持 Markdown