Blazor Server集成Active Directory与.NET Core 5 MVC及Azure AD有何差异?
解答
原有AD代码适配说明
你之前在MVC中写的LDAP查询逻辑90%可以直接复用,仅需要调整用户身份的获取方式:
Blazor Server的请求生命周期和MVC不同,它通过SignalR长连接处理交互,HttpContext仅在初始建立连接时有效,不能在后续业务逻辑中直接访问HttpContext.User获取当前登录用户,你需要通过AuthenticationStateProvider拿到用户身份后作为参数传入AD查询方法。
额外注意:.NET 6+版本需要手动安装System.DirectoryServices NuGet包,该类库默认不包含在Blazor Server框架中;部署时应用池身份需要拥有LDAP访问权限,和MVC部署要求一致。
实现示例
1. 封装AD查询服务
首先将原有逻辑改造为可注入的服务:
// 自定义AD用户信息返回模型 public class ADUserInfo { public string GivenName { get; set; } public string Surname { get; set; } public string HomePhone { get; set; } public string Email { get; set; } } // 服务接口 public interface IADService { ADUserInfo GetUserADInfo(System.Security.Claims.ClaimsPrincipal currentUser); } // 服务实现 public class ADService : IADService { private readonly YourDbContext _context; // 替换为你自己的DbContext类名 public ADService(YourDbContext context) { _context = context; } public ADUserInfo GetUserADInfo(System.Security.Claims.ClaimsPrincipal currentUser) { var adInfo = new ADUserInfo(); if (!currentUser.Identity.IsAuthenticated) return adInfo; var username = currentUser.Identity.Name.Split('\\').Last(); var ldapConnection = CreateDirectoryEntry(); var search = new DirectorySearcher(ldapConnection) { Filter = $"(cn={username})" }; var result = search.FindOne(); if (result == null) return adInfo; var dsEntry = result.GetDirectoryEntry(); adInfo.GivenName = dsEntry.Properties["givenName"][0]?.ToString(); adInfo.Surname = dsEntry.Properties["sn"][0]?.ToString(); adInfo.Email = dsEntry.Properties["mail"][0]?.ToString(); adInfo.HomePhone = dsEntry.Properties["homePhone"][0]?.ToString(); return adInfo; } private DirectoryEntry CreateDirectoryEntry() { string adServer = _context.ApplicConfs.Select(s => s.Ldapconn).FirstOrDefault(); string ldapPath = _context.ApplicConfs.Select(s => s.Ldappath).FirstOrDefault(); var ldapConnection = new DirectoryEntry(adServer) { Path = ldapPath, AuthenticationType = AuthenticationTypes.Secure }; return ldapConnection; } }
然后在Program.cs中注册服务:
builder.Services.AddScoped<IADService, ADService>();
2. Blazor组件预填充示例
在需要展示用户信息的组件中注入服务,初始化时获取AD信息填充表单:
@page "/user/form" @inject AuthenticationStateProvider AuthStateProvider @inject IADService AdService <EditForm Model="@FormModel"> <div class="form-group"> <label>名</label> <InputText @bind-Value="FormModel.GivenName" class="form-control" /> </div> <div class="form-group"> <label>姓</label> <InputText @bind-Value="FormModel.Surname" class="form-control" /> </div> <div class="form-group"> <label>邮箱</label> <InputText @bind-Value="FormModel.Email" class="form-control" /> </div> <div class="form-group"> <label>家庭电话</label> <InputText @bind-Value="FormModel.HomePhone" class="form-control" /> </div> </EditForm> @code { // 你的表单模型类 public class UserFormModel { public string GivenName { get; set; } public string Surname { get; set; } public string Email { get; set; } public string HomePhone { get; set; } } private UserFormModel FormModel { get; set; } = new(); protected override async Task OnInitializedAsync() { // 获取当前登录用户 var authState = await AuthStateProvider.GetAuthenticationStateAsync(); if (authState.User.Identity.IsAuthenticated) { // 查询AD信息填充表单 var adUserInfo = AdService.GetUserADInfo(authState.User); FormModel.GivenName = adUserInfo.GivenName; FormModel.Surname = adUserInfo.Surname; FormModel.Email = adUserInfo.Email; FormModel.HomePhone = adUserInfo.HomePhone; } } }
本地AD与Azure AD的差异
两者实现逻辑差异非常大:
- 本地AD基于LDAP协议查询,使用
System.DirectoryServices类库,适配Windows身份认证场景,你现有的逻辑基本可以直接复用 - Azure AD没有LDAP访问能力,需要调用微软Graph API查询用户属性,认证逻辑走OAuth2/OpenID Connect协议,和你当前使用的Windows身份认证完全不兼容,不需要参考Azure AD的集成示例
内容的提问来源于stack exchange,提问作者Lyndon Sundmark
相关产品推荐
相关产品推荐

