---
title: "sdk/windows"
description: "适用于 WinUI 3 应用的 C# / .NET SDK，使用 WebView2 进行授权、PKCE S256 和 DPAPI 保护的 IsolatedStorage 进行 token 持久化。"
locale: "zh-Hans"
---

> Documentation Index
> Fetch the relevant documentation index at: https://vonvon.id/zh-hans/sdks/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/windows

## 状态

包状态为**已在本地实现并验证**。跨平台 .NET 单元测试套件已通过。WebView2、DPAPI、WinUI 3 和真实 IdP 往返仍需 Windows 集成环境。本页记录的是已实现行为，不代表已具备生产就绪状态。

Registry 状态:UNPUBLISHED。此 SDK 只能从仓库源码 checkout 安装；不要使用外部 package registry。

## 要求

- .NET 8 和 Windows App SDK 1.6+
- WebView2 运行时（常青版——随 Microsoft Edge 预装）
- 应用必须在项目文件中设置 &lt;UseWinUI&gt;true&lt;/UseWinUI&gt;

## 安装

从应用项目文件添加指向源码 checkout 的 ProjectReference:

```xml
<ItemGroup>
  <ProjectReference Include="../vonvon/sdk/windows/Vonvon.Windows.csproj" />
</ItemGroup>
```

## 快速开始

```csharp
using Vonvon.Windows;

// 1. Configure in App.xaml.cs OnLaunched.
VonvonClient.Shared.Configure(new VonvonConfiguration
{
Issuer      = new Uri("https://vonvon.id"),
ClientId    = "your_client_id",
RedirectUri = "com.example.myapp://auth/callback",
// Scopes default: openid profile email. offline_access is rejected until DPoP is implemented.
});

// 2. Sign in (opens embedded WebView2 window)
VonvonSession session = await VonvonClient.Shared.SignInAsync();
Console.WriteLine($"Signed in: {session.User.Email}");

// 3. Get the current unexpired access token. Expiry requires reauthorization.
string? token = await VonvonClient.Shared.GetAccessToken();

// 4. Get the current unexpired session.
VonvonSession? current = await VonvonClient.Shared.GetSession();

// 5. Clear local state.
await VonvonClient.Shared.SignOut();
```

## 自定义 URI scheme callback（可选）

如果使用自定义 URI scheme 重定向而非 WebView2 嵌入窗口，请将协议激活 URI 转发给 `HandleRedirectAsync`：

```csharp
// App.xaml.cs
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.Protocol)
{
    var protocolArgs = (ProtocolActivatedEventArgs)args;
    await VonvonClient.Shared.HandleRedirectAsync(protocolArgs.Uri);
}
}
```

## 核心 API

| 方式 | 描述 |
| --- | --- |
| `Configure(VonvonConfiguration)` | 初始化 SDK。在应用启动时调用一次。 |
| `SignInAsync(options?, ct)` | 以 PKCE S256 打开嵌入式 WebView2 授权窗口。完成后返回 VonvonSession。 |
| `HandleRedirectAsync(Uri, ct)` | 处理自定义 URI scheme callback 并交换授权码。 |
| `GetSession(ct)` | 返回当前未过期的会话；如果已过期，则清除本地状态并返回 null。 |
| `GetAccessToken(options?, ct)` | 返回当前未过期的 access token；ForceRefresh 会清除会话并要求重新授权。 |
| `SignOut(ct)` | 从 DPAPI 保护的 IsolatedStorage 中清除本地会话 token。 |
| `SetTokenStorage(ITokenStorage)` | 用自定义 ITokenStorage 实现替换默认的 DpapiTokenStorage。 |

## 存储适配器

默认存储使用 DPAPI（CurrentUser 范围）加密 token，并将其持久化到 IsolatedStorage。实现 `ITokenStorage` 以使用 Windows Hello 或 Credential Manager：

```csharp
public sealed class MyCustomStorage : ITokenStorage
{
public Task SaveAsync(StoredTokenSet tokens, CancellationToken ct = default) { ... }
public Task<StoredTokenSet?> LoadAsync(CancellationToken ct = default) { ... }
public Task ClearAsync(CancellationToken ct = default) { ... }
}
VonvonClient.Shared.SetTokenStorage(new MyCustomStorage());
```

## 依赖项

| 包 | 版本 | 用途 |
| --- | --- | --- |
| `Microsoft.WindowsAppSDK` | 1.6.250228002 | WinUI 3 宿主和 WebView2 嵌入 |
| `Microsoft.Web.WebView2` | 1.0.3065.39 | 基于 Chromium 的嵌入式授权窗口 |
| `System.Security.Cryptography.ProtectedData` | 8.0.0 | DPAPI token 静态加密 |

## 安全

- 公共客户端——不存储或传输客户端密钥。
- 仅 PKCE S256。服务器拒绝 plain challenge 方式。
- 使用 DPAPI（CurrentUser 范围）加密 token，并存储在 IsolatedStorage 中。其他 Windows 用户账户无法访问。
- 每次请求生成 OAuth state；在重定向时验证以防 CSRF。

## 已知限制

- 必须安装 WebView2 运行时。WebAuthenticationBroker 作为回退方案已在计划中，但尚未实现。
- 基于 JWKS 的 ID token 验签和 end\_session 登出已实现并完成本地测试。真实 Windows WebView2、DPAPI 和 IdP 往返验证前仍不具备 L4 支持。
- DpapiTokenStorage 不能在非 Windows 平台上运行。交叉编译时请使用其他 ITokenStorage 实现。

Source: https://vonvon.id/zh-hans/sdks/windows/index.mdx
