keycloak 官方无 c# sdk,所谓 keycloak_c# 并非 nuget 包;主流方案是使用社区库 keycloak.net 或直接调用 rest api;blazor wasm 需走标准 oidc 流程,不可直接用 keycloak.net。

Keycloak 官方没有提供 C# SDK,所谓“Keycloak C# SDK”或“Keycloak\_c#”不是官方维护的库,也不在 Keycloak 项目中。你无法通过 NuGet 安装名为 Keycloak_c# 的包——它不存在。
为什么搜不到 Keycloak_c# NuGet 包?
这是一个长期存在的误解,源于早期社区有人将自己封装的 Keycloak REST API 调用代码命名为 Keycloak_c# 并上传到 GitHub(非 NuGet),但未发布到官方包源,也未持续维护。目前主流、可用、有维护的 C# 方案只有两类:
- 直接调用 Keycloak Admin REST API(HTTP + JSON)
- 使用第三方封装库,如
Keycloak.Net(GitHub:neurospeech/keycloak.net,NuGet 包名:Keycloak.Net)
注意:Keycloak.Net 不是 Red Hat 官方出品,但它是目前最活跃、文档较全、支持 .NET 6+ 和 Keycloak 17+ 的社区库。
如何用 Keycloak.Net 获取用户 Token(登录)?
这是最常见的起点:让 Web 或桌面应用用户通过 Keycloak 登录,并拿到 access_token。关键不是“SDK 封装多漂亮”,而是正确构造请求参数和处理响应。
示例(使用 Keycloak.Net):
var client = new KeycloakClient(new KeycloakClientConfiguration
{
Realm = "myrealm",
ClientId = "myclient",
ClientSecret = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
BaseUrl = "https://auth.example.com/auth"
});
<p>// 注意:LoginAsync 默认走 confidential client 的 client_credentials 流程
// 若你是 public client(如 Blazor WASM),必须用 Authorization Code Flow + PKCE
// 此时不能用 LoginAsync,得手动跳转 /protocol/openid-connect/auth</p>
容易踩的坑:
-
ClientSecret只对confidential类型客户端有效;public客户端必须禁用该字段并走前端重定向流程 - Keycloak 20+ 默认关闭
Direct Access Grants(即密码模式),LoginAsync(username, password)会直接失败,除非你在管理后台显式开启 - 返回的
TokenResponse中,AccessToken是 JWT 字符串,需自行解析(如用System.IdentityModel.Tokens.Jwt)验证签名和有效期
如何调用 Keycloak Admin API 管理用户(如创建、禁用)?
Admin API 需要管理员 token(bearer token),且对应 client 必须开启 Service Accounts Enabled 并分配 realm-admin 角色。
实操建议:
- 不要用
Keycloak.Net.AdminClient的默认构造函数——它不自动刷新 token,过期后所有请求 401 - 手动获取 admin token 更可控(示例用
HttpClient):
var tokenResp = await new HttpClient().PostAsJsonAsync(
"https://auth.example.com/auth/realms/master/protocol/openid-connect/token",
new Dictionary<string string>
{
["client_id"] = "admin-cli",
["grant_type"] = "password",
["username"] = "admin",
["password"] = "xxx",
["client_secret"] = "" // admin-cli 是 public client,无 secret
});</string>
拿到 access_token 后,再调 Admin API:
var usersResp = await http.GetAsync(
"https://auth.example.com/auth/admin/realms/myrealm/users?username=john");
注意路径中的 /admin/realms/{realm} 是固定格式,漏掉 /admin 会 404;Keycloak 21+ 还要求 Header 带 Authorization: Bearer {token},否则 401。
Blazor WASM 能否用 Keycloak.Net?
不能直接用——因为 Keycloak.Net 内部依赖 HttpClientHandler 和服务端证书验证逻辑,在浏览器环境不可用。WASM 必须走标准 OIDC 流程:
- 用
Microsoft.AspNetCore.Components.WebAssembly.Authentication - 配置
OidcProviderOptions指向 Keycloak 的issuer(如https://auth.example.com/auth/realms/myrealm) - 确保 Keycloak client 的
Valid Redirect URIs包含你的 WASM 应用地址(如https://app.example.com/authentication/login-callback)
Keycloak 返回的 token 默认不含 groups 或自定义 realm roles,需要在 client scope 中绑定 realm roles mapper,并设为 “Add to ID token” 或 “Add to access token” —— 否则 ClaimsPrincipal 里查不到角色。
真正麻烦的从来不是“怎么调接口”,而是 Keycloak 后台的 client type、access type、redirect URIs、mappers、roles assignment 这些配置项之间相互耦合。一个配错,错误信息就只报 401 或 403,根本看不出哪一环断了。











