ASP.Net Core 6服务访问WindowsIdentity.Name时触发Safe handle已关闭异常
ASP.NET Core 6 Windows身份验证中访问Identity.Name时抛出ObjectDisposedException
问题背景
使用ASP.NET Core 6开发内部Web服务,通过IIS启用Windows身份验证,依赖AuthenticationStateProvider.GetAuthenticationStateAsync().User获取用户身份。多数场景运行正常,但日志中频繁出现访问Windows Identity的Name属性时抛出ObjectDisposedException(提示Safe handle已关闭),未手动释放相关资源,无法定位根源。尝试使用ServerAuthenticationStateProvider但在Blazor Server环境下不可用。
异常详情
System.ObjectDisposedException: Safe handle has been closed. Object name: 'SafeHandle'. at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) at Interop.Advapi32.GetTokenInformation(SafeAccessTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength) at System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass, Boolean nullOnInvalidParam) at System.Security.Principal.WindowsIdentity.get_User() at System.Security.Principal.WindowsIdentity.<GetName>b__55_0() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle token, Action action) at System.Security.Principal.WindowsIdentity.GetName() at Server.Common.Services.ClaimsPrincipalService.GetCurrentUserAccountName()
相关代码
ClaimsPrincipalService实现
public class ClaimsPrincipalService { private readonly AuthenticationStateProvider AuthenticationStateProvider; private readonly Serilog.ILogger Logger; public ClaimsPrincipalService(AuthenticationStateProvider authenticationStateProvider, Serilog.ILogger logger) { AuthenticationStateProvider = authenticationStateProvider; Logger = logger; } public async Task<string?> GetCurrentUserAccountName() { try { var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); var user = authState.User; if (user.Identity != null && user.Identity.IsAuthenticated && user.Identity.Name != null) { var identityName = user.Identity.Name; int stop = identityName.IndexOf(@"\"); var userId = stop > -1 ? identityName.Substring(stop + 1, identityName.Length - stop - 1) : string.Empty; userId = userId.ToUpper(); return userId; } else { Logger.Warning("User Identity/Authentication could not be verified"); } } catch (Exception ex) { Logger.Error(ex, "Exception during GetClaimsPrincipalDataAsync method"); } return null; } }
服务注册(Program.cs)
builder.Services.AddScoped<ClaimsPrincipalService, ClaimsPrincipalService>();
解决方案分析
1. 立即提取并缓存用户信息
Windows Identity的Name属性内部依赖未托管的安全句柄,请求上下文回收后该句柄会被释放。禁止延迟访问Identity.Name,需在获取AuthenticationState后同步提取所需信息:
public async Task<string?> GetCurrentUserAccountName() { try { var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); var user = authState.User; if (user.Identity is WindowsIdentity windowsIdentity && windowsIdentity.IsAuthenticated) { // 同步获取Name并处理,避免后续访问已释放的句柄 var identityName = windowsIdentity.Name; if (!string.IsNullOrEmpty(identityName)) { int stop = identityName.IndexOf(@"\"); var userId = stop > -1 ? identityName.Substring(stop + 1).ToUpper() : string.Empty; return userId; } } Logger.Warning("User Identity/Authentication could not be verified"); } catch (ObjectDisposedException ex) { Logger.Error(ex, "Windows Identity handle has been disposed"); // 可根据业务需求添加重试或默认值逻辑 } catch (Exception ex) { Logger.Error(ex, "Exception during GetCurrentUserAccountName method"); } return null; }
2. 检查服务生命周期匹配
ClaimsPrincipalService是Scoped服务,绝对不能注入到Singleton服务中,否则会导致请求上下文回收后,Singleton服务仍持有已释放的Identity引用,引发异常。
3. 确认Windows身份验证配置
确保Program.cs中正确配置身份验证:
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme); builder.Services.AddAuthorization();
同时在IIS站点配置中启用Windows身份验证,禁用匿名身份验证。
4. Blazor Server环境特殊处理
Blazor Server中AuthenticationState与电路关联,电路断开时Identity句柄会被释放:
- 在组件/页面初始化阶段立即提取用户信息并缓存
- 使用
CircuitHandler监听电路状态,在电路断开时清理相关缓存
内容的提问来源于stack exchange,提问作者Wolfware
相关产品推荐
相关产品推荐

