如何为Elsa v3配置Azure AD身份验证?
Elsa v3 配置Azure AD身份验证方案解析与修正
当前方案的问题分析
你当前的代码存在两个核心问题:
- 存储注册错误:
AddUserStore<User>()和AddRoleStore<Role>()用法不符合Microsoft Identity规范——这两个方法的泛型参数需要传入实现了对应接口的存储类型,而非User/Role实体类。Azure AD作为外部身份提供者,并不直接提供IUserStore<User>或IRoleStore<Role>的本地实现,因此这两行代码会导致DI容器无法找到对应服务,触发报错。 - 接口适配逻辑偏差:Elsa的
IUserStore/IRoleStore是自定义抽象,与Microsoft Identity的同名泛型接口完全独立。你试图注入Microsoft Identity的存储接口,但Azure AD场景下无需本地存储,应通过Graph API获取用户/角色数据。
当前方案修正步骤
1. 移除错误的存储注册代码
将UseAzureIdentityProvider方法中的错误注册代码删除,替换为Microsoft Graph服务注册(用于获取Azure AD用户/角色数据):
public static class ElsaAzureActiveDirectoryIdentityAdapterServiceCollectionExtensions { public static void UseAzureIdentityProvider(this IdentityFeature identity, IConfiguration configuration) { // 注册Microsoft Graph服务(用于访问Azure AD数据) var tenantId = configuration["AzureAd:TenantId"]; var clientId = configuration["AzureAd:ClientId"]; var clientSecret = configuration["AzureAd:ClientSecret"]; identity.Services.AddMicrosoftGraph(options => { options.Scopes = "User.Read Directory.Read.All"; }).AddAuthenticationProvider(new ClientCredentialProvider( new ClientCredential(clientId, clientSecret), $"https://login.microsoftonline.com/{tenantId}/v2.0")); // 注册适配器 identity.Services.AddSingleton<ElsaAzureActiveDirectoryIdentityAdapter>(); identity.Services.AddSingleton<IRoleStore>(provider => provider.GetRequiredService<ElsaAzureActiveDirectoryIdentityAdapter>()); identity.Services.AddSingleton<IUserStore>(provider => provider.GetRequiredService<ElsaAzureActiveDirectoryIdentityAdapter>()); identity.UserStore = provider => provider.GetRequiredService<IUserStore>(); identity.RoleStore = provider => provider.GetRequiredService<IRoleStore>(); } }
2. 修改适配器类,通过Graph API获取数据
调整适配器,注入GraphServiceClient而非Microsoft Identity的存储接口,直接从Azure AD获取用户/角色:
public class ElsaAzureActiveDirectoryIdentityAdapter(GraphServiceClient graphClient) : IRoleStore, IUserStore { #region Role Store Methods public Task AddAsync(Role role, CancellationToken cancellationToken = default) => throw new NotImplementedException("Azure AD角色需在门户管理,不支持本地添加"); public Task DeleteAsync(RoleFilter filter, CancellationToken cancellationToken = default) => throw new NotImplementedException("Azure AD角色需在门户管理,不支持本地删除"); public Task SaveAsync(Role role, CancellationToken cancellationToken = default) => throw new NotImplementedException("Azure AD角色需在门户管理,不支持本地修改"); public async Task<Role?> FindAsync(RoleFilter filter, CancellationToken cancellationToken = default) { if (filter.Id != null) { var azureRole = await graphClient.DirectoryRoles[filter.Id].Request().GetAsync(cancellationToken); return new Role { Id = azureRole.Id, Name = azureRole.DisplayName }; } return null; } public async Task<IEnumerable<Role>> FindManyAsync(RoleFilter filter, CancellationToken cancellationToken = default) { var roles = await graphClient.DirectoryRoles.Request().GetAsync(cancellationToken); return roles.Select(r => new Role { Id = r.Id, Name = r.DisplayName }); } #endregion #region User Store Methods public Task SaveAsync(User user, CancellationToken cancellationToken = default) => throw new NotImplementedException("Azure AD用户需在门户管理,不支持本地修改"); public Task DeleteAsync(UserFilter filter, CancellationToken cancellationToken = default) => throw new NotImplementedException("Azure AD用户需在门户管理,不支持本地删除"); public async Task<User?> FindAsync(UserFilter filter, CancellationToken cancellationToken = default) { if (filter.Id != null) { var azureUser = await graphClient.Users[filter.Id].Request().GetAsync(cancellationToken); return MapToElsaUser(azureUser); } if (filter.Name != null) { var users = await graphClient.Users.Request() .Filter($"userPrincipalName eq '{filter.Name}'") .GetAsync(cancellationToken); return users.FirstOrDefault()?.MapToElsaUser(); } return null; } private User MapToElsaUser(Microsoft.Graph.Models.User azureUser) { return new User { Id = azureUser.Id, Name = azureUser.UserPrincipalName, Email = azureUser.Mail ?? azureUser.UserPrincipalName }; } #endregion }
Elsa Studio v3(Blazor WASM)配置Azure AD的标准方法
如果无需自定义用户存储,仅需实现Azure AD认证,可采用以下更简单的方案:
1. 后端API配置(ASP.NET Core)
// 注册Azure AD JWT认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); // 配置Elsa使用JWT认证 builder.Services.AddElsa(elsa => { elsa.UseIdentity(identity => { identity.TokenOptions = options => { options.ValidIssuer = builder.Configuration["AzureAd:Issuer"]; options.ValidAudience = builder.Configuration["AzureAd:Audience"]; }; identity.UseJwtAuthentication(); }); });
2. Blazor WASM客户端配置
// 注册MSAL认证 builder.Services.AddMsalAuthentication(options => { builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); options.ProviderOptions.DefaultAccessTokenScopes.Add("api://your-backend-api-client-id/access_as_user"); });
3. 配置文件(appsettings.json)
{ "AzureAd": { "Authority": "https://login.microsoftonline.com/your-tenant-id", "ClientId": "your-client-id", "Audience": "api://your-backend-api-client-id", "ValidateAuthority": true } }
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

