Blazor AD 身份验证安全句柄已关闭
Blazor AD authentication Safe handle has been closed
我正在尝试使用 Blazor(服务器端和 .net core 3.0 preview-6)进行 AD 身份验证。
当我添加 @attribute [Authorize(Roles = "DomainUsers")]
时,出现以下错误。
如果我更改为策略,我会得到同样的错误。但是,如果我只使用 [Authorize]
,我不会收到错误消息。
当我单击菜单中的 link 时会发生这种情况。
如果我在浏览器中写入直接路径,我会按预期工作。
public Startup(IConfiguration config)
{
Configuration = config;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
services.AddAuthentication();
services.AddAuthorization();
services.AddHttpClient();
var appDB = Configuration.GetConnectionString("AppDB");
services.Configure<CtApiSettings>(Configuration.GetSection("CtApiSettings"));
services.AddDbContext<ApplicationContext>(o => o.UseSqlServer(appDB, builder =>
{
builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
}));
services.AddToaster(config =>
{
config.PositionClass = Defaults.Classes.Position.TopFullWidth;
config.PreventDuplicates = false;
config.NewestOnTop = false;
config.ShowTransitionDuration = 500;
config.VisibleStateDuration = 5000;
config.HideTransitionDuration = 500;
});
// Setup HttpClient for server side in a client side compatible fashion
services.AddScoped<HttpClient>(s =>
{
// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
var uriHelper = s.GetRequiredService<IUriHelper>();
return new HttpClient
{
BaseAddress = new Uri(uriHelper.GetBaseUri())
};
});
ActiveDirectoryModel adm = new ActiveDirectoryModel();
Configuration.GetSection("AD").Bind(adm);
services.Configure<ActiveDirectoryModel>(Configuration.GetSection("AD"));
services.AddScoped<ExcelExportService>();
services.AddScoped<IAreaService, AreaService>();
services.AddScoped<IUserProvider>(x => new UserProvider(adm));
services.AddScoped<IAdminService, AdminService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapRazorPages();
//endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
Error: System.ObjectDisposedException: Safe handle has been closed.
Object name: 'SafeHandle'. at
System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean&
success) 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.b__51_0() at
System.Security.Principal.WindowsIdentity.<>c__DisplayClass67_0.b__0(Object
) at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown --- at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle
token, Action action) at
System.Security.Principal.WindowsIdentity.RunImpersonated(SafeAccessTokenHandle
safeAccessTokenHandle, Action action) at
System.Security.Principal.WindowsIdentity.GetName() at
System.Security.Principal.WindowsIdentity.get_Name() at
System.Security.Principal.WindowsIdentity.InitializeClaims() at
System.Security.Principal.WindowsIdentity.get_Claims()+MoveNext()
at System.Security.Claims.ClaimsIdentity.HasClaim(String type, String
value) at System.Security.Claims.ClaimsPrincipal.IsInRole(String
role) at System.Security.Principal.WindowsPrincipal.IsInRole(String
role) at
Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.<>c__DisplayClass4_0.b__0(String
r) at System.Linq.Enumerable.Any[TSource](IEnumerable1 source,
Func
2 predicate) at
Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.HandleRequirementAsync(AuthorizationHandlerContext
context, RolesAuthorizationRequirement requirement) at
Microsoft.AspNetCore.Authorization.AuthorizationHandler1.HandleAsync(AuthorizationHandlerContext
context) at
Microsoft.AspNetCore.Authorization.Infrastructure.PassThroughAuthorizationHandler.HandleAsync(AuthorizationHandlerContext
context) at
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal
user, Object resource, IEnumerable
1 requirements) at
Microsoft.AspNetCore.Components.AuthorizeViewCore.IsAuthorizedAsync(ClaimsPrincipal
user) at
Microsoft.AspNetCore.Components.AuthorizeViewCore.OnParametersSetAsync()
at
Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task
task) at
Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
我有同样的问题 - .Net Core 3.0-preview 6 的 Blazor 应用程序。
我正在使用自定义 AuthorizationHandler
以及身份框架。尝试使用 context.User.Identity.Name
.
读取当前用户名时,在 HandleRequirementAsync
内抛出错误
根据 github 上的 issue tracker:
Currently the built-in internal default FixedAuthenticationStateProvider assumes the authentication state is fixed for the lifetime of the circuit, as its name implies. However this isn't adequate for Windows authentication, as the WindowsPrincipal is connected to underlying OS services and can't continue to be used if the original HTTP request has completed. Trying to call things like IsInRole will throw if the principal has already been disposed
修复已合并到 master,将与 asp.net 核心一起发布 3.0.0-preview8
更新: 似乎已解决,see here 升级到预览版 8 并修复重大更改。
我正在尝试使用 Blazor(服务器端和 .net core 3.0 preview-6)进行 AD 身份验证。
当我添加 @attribute [Authorize(Roles = "DomainUsers")]
时,出现以下错误。
如果我更改为策略,我会得到同样的错误。但是,如果我只使用 [Authorize]
,我不会收到错误消息。
当我单击菜单中的 link 时会发生这种情况。 如果我在浏览器中写入直接路径,我会按预期工作。
public Startup(IConfiguration config)
{
Configuration = config;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
services.AddAuthentication();
services.AddAuthorization();
services.AddHttpClient();
var appDB = Configuration.GetConnectionString("AppDB");
services.Configure<CtApiSettings>(Configuration.GetSection("CtApiSettings"));
services.AddDbContext<ApplicationContext>(o => o.UseSqlServer(appDB, builder =>
{
builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
}));
services.AddToaster(config =>
{
config.PositionClass = Defaults.Classes.Position.TopFullWidth;
config.PreventDuplicates = false;
config.NewestOnTop = false;
config.ShowTransitionDuration = 500;
config.VisibleStateDuration = 5000;
config.HideTransitionDuration = 500;
});
// Setup HttpClient for server side in a client side compatible fashion
services.AddScoped<HttpClient>(s =>
{
// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
var uriHelper = s.GetRequiredService<IUriHelper>();
return new HttpClient
{
BaseAddress = new Uri(uriHelper.GetBaseUri())
};
});
ActiveDirectoryModel adm = new ActiveDirectoryModel();
Configuration.GetSection("AD").Bind(adm);
services.Configure<ActiveDirectoryModel>(Configuration.GetSection("AD"));
services.AddScoped<ExcelExportService>();
services.AddScoped<IAreaService, AreaService>();
services.AddScoped<IUserProvider>(x => new UserProvider(adm));
services.AddScoped<IAdminService, AdminService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapRazorPages();
//endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
Error: System.ObjectDisposedException: Safe handle has been closed. Object name: 'SafeHandle'. at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) 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.b__51_0() at System.Security.Principal.WindowsIdentity.<>c__DisplayClass67_0.b__0(Object ) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location where exception was thrown --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle token, Action action) at System.Security.Principal.WindowsIdentity.RunImpersonated(SafeAccessTokenHandle safeAccessTokenHandle, Action action) at System.Security.Principal.WindowsIdentity.GetName() at System.Security.Principal.WindowsIdentity.get_Name() at System.Security.Principal.WindowsIdentity.InitializeClaims() at System.Security.Principal.WindowsIdentity.get_Claims()+MoveNext()
at System.Security.Claims.ClaimsIdentity.HasClaim(String type, String value) at System.Security.Claims.ClaimsPrincipal.IsInRole(String role) at System.Security.Principal.WindowsPrincipal.IsInRole(String role) at Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.<>c__DisplayClass4_0.b__0(String r) at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func
2 predicate) at Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement) at Microsoft.AspNetCore.Authorization.AuthorizationHandler1.HandleAsync(AuthorizationHandlerContext context) at Microsoft.AspNetCore.Authorization.Infrastructure.PassThroughAuthorizationHandler.HandleAsync(AuthorizationHandlerContext context) at Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal user, Object resource, IEnumerable
1 requirements) at Microsoft.AspNetCore.Components.AuthorizeViewCore.IsAuthorizedAsync(ClaimsPrincipal user) at Microsoft.AspNetCore.Components.AuthorizeViewCore.OnParametersSetAsync() at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task) at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
我有同样的问题 - .Net Core 3.0-preview 6 的 Blazor 应用程序。
我正在使用自定义 AuthorizationHandler
以及身份框架。尝试使用 context.User.Identity.Name
.
HandleRequirementAsync
内抛出错误
根据 github 上的 issue tracker:
Currently the built-in internal default FixedAuthenticationStateProvider assumes the authentication state is fixed for the lifetime of the circuit, as its name implies. However this isn't adequate for Windows authentication, as the WindowsPrincipal is connected to underlying OS services and can't continue to be used if the original HTTP request has completed. Trying to call things like IsInRole will throw if the principal has already been disposed
修复已合并到 master,将与 asp.net 核心一起发布 3.0.0-preview8
更新: 似乎已解决,see here 升级到预览版 8 并修复重大更改。