如何使用Dotnet Core从Keycloak获取指定Realm的全部用户列表
Keycloak 客户端前置配置
首先需要给你的mvcdemo客户端开通用户查询权限,否则调用接口会返回403无权限错误:
- 登录Keycloak管理控制台,进入
KeycloakMVCDemoRealm - 打开「客户端」菜单,找到
mvcdemo客户端进入配置页 - 开启「服务账号已启用」选项,保存配置
- 切换到「服务账号角色」标签,点击「分配角色」,筛选「客户端」角色,找到
realm-management客户端,勾选view-users权限后保存
.NET Core MVC 代码实现
1. 配置绑定实体
先创建配置映射类,用于绑定appsettings.json中的Keycloak配置:
public class KeycloakSettings { public string Authority { get; set; } public string ClientId { get; set; } public string ClientSecret { get; set; } // 自动提取Realm名称 public string RealmName => Authority.Split('/').Last(); // 拼接Admin API基础地址 public string AdminApiBase => Authority[..Authority.IndexOf("/realms/", StringComparison.Ordinal)] + "/admin/realms/"; }
2. 注册服务
在Program.cs中添加服务注册:
// 绑定Keycloak配置 builder.Services.Configure<KeycloakSettings>(builder.Configuration.GetSection("keycloak")); // 注册HttpClient builder.Services.AddHttpClient(); // 注册用户查询服务 builder.Services.AddScoped<KeycloakUserService>();
3. 实现用户查询服务
创建KeycloakUserService类封装用户查询逻辑:
using System.Net.Http.Headers; using System.Text.Json.Serialization; using Microsoft.Extensions.Options; public class KeycloakUserService { private readonly HttpClient _httpClient; private readonly KeycloakSettings _keycloakSettings; public KeycloakUserService(HttpClient httpClient, IOptions<KeycloakSettings> keycloakOptions) { _httpClient = httpClient; _keycloakSettings = keycloakOptions.Value; } public async Task<List<KeycloakUser>> GetAllRealmUsersAsync() { // 第一步:使用客户端模式获取访问令牌 var tokenContent = new FormUrlEncodedContent(new Dictionary<string, string> { {"grant_type", "client_credentials"}, {"client_id", _keycloakSettings.ClientId}, {"client_secret", _keycloakSettings.ClientSecret} }); var tokenResp = await _httpClient.PostAsync( $"{_keycloakSettings.Authority}/protocol/openid-connect/token", tokenContent); tokenResp.EnsureSuccessStatusCode(); var tokenResult = await tokenResp.Content.ReadFromJson<TokenResult>(); // 第二步:携带令牌调用Admin API获取用户列表 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken); // 如需分页可添加first、max参数,默认单次最多返回100条 var userResp = await _httpClient.GetAsync( $"{_keycloakSettings.AdminApiBase}{_keycloakSettings.RealmName}/users?max=1000"); userResp.EnsureSuccessStatusCode(); return await userResp.Content.ReadFromJson<List<KeycloakUser>>() ?? new List<KeycloakUser>(); } } // 令牌返回实体 public class TokenResult { [JsonPropertyName("access_token")] public string AccessToken { get; set; } } // Keycloak用户实体,可根据需要扩展字段 public class KeycloakUser { [JsonPropertyName("id")] public string Id { get; set; } [JsonPropertyName("username")] public string Username { get; set; } [JsonPropertyName("email")] public string Email { get; set; } [JsonPropertyName("firstName")] public string FirstName { get; set; } [JsonPropertyName("lastName")] public string LastName { get; set; } [JsonPropertyName("enabled")] public bool IsEnabled { get; set; } }
4. Controller调用示例
在需要的控制器中注入服务直接调用即可:
public class UserController : Controller { private readonly KeycloakUserService _userService; public UserController(KeycloakUserService userService) { _userService = userService; } public async Task<IActionResult> List() { var allUsers = await _userService.GetAllRealmUsersAsync(); return View(allUsers); } }
注意事项
- 如果你的Keycloak版本高于17,默认部署路径已经移除了
/auth前缀,需要根据实际部署情况调整AdminApiBase的拼接逻辑 - 所有Admin API的调用必须在服务端完成,禁止将ClientSecret、访问令牌泄露到前端
- 当Realm用户数超过1000时,请通过
first(偏移量)和max(每页数量)参数分页查询,避免接口超时
内容的提问来源于stack exchange,提问作者soundar rajan
相关产品推荐
相关产品推荐

