Blazor AD身份验证安全句柄已关闭

时间:2019-06-18 12:48:53

标签: c# blazor blazor-server-side asp.net-core-3.0

我正在尝试使用Blazor(服务器端和.net core 3.0预览版6)进行AD身份验证。

当我添加@attribute [Authorize(Roles = "DomainUsers")]时,出现以下错误。

如果我更改为Policy,则会收到相同的错误。但是,如果我仅使用[Authorize],则不会收到错误消息。

当我单击菜单中的链接时会发生这种情况。 如果我在浏览器中编写直接路径,则可以正常工作。

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");
        });
    }
  

错误:System.ObjectDisposedException:安全句柄已关闭。   对象名称:“ SafeHandle”。在   System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean&   成功)   System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle,   布尔值和成功)   Interop.Advapi32.GetTokenInformation(SafeAccessTokenHandle   TokenHandle,UInt32 TokenInformationClass,SafeLocalAllocHandle   TokenInformation,UInt32 TokenInformationLength,UInt32和ReturnLength)   在   System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeAccessTokenHandle   tokenHandle,TokenInformationClass,TokenInformationClass,布尔   nullOnInvalidParam)   System.Security.Principal.WindowsIdentity.get_User()位于   System.Security.Principal.WindowsIdentity.b__51_0()在   System.Security.Principal.WindowsIdentity。<> c__DisplayClass67_0.b__0(Object   ) 在   System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态)   ---从上一个引发异常的位置开始的堆栈跟踪-   System.Threading.ExecutionContext.RunInternal(ExecutionContext   executeContext,ContextCallback回调,对象状态),位于   System.Threading.ExecutionContext.Run(ExecutionContext   executeContext,ContextCallback回调,对象状态),位于   System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle   令牌,动作)   System.Security.Principal.WindowsIdentity.RunImpersonated(SafeAccessTokenHandle   safeAccessTokenHandle,动作)   System.Security.Principal.WindowsIdentity.GetName()在   System.Security.Principal.WindowsIdentity.get_Name()在   System.Security.Principal.WindowsIdentity.InitializeClaims()在   System.Security.Principal.WindowsIdentity.get_Claims()+ MoveNext()
  在System.Security.Claims.ClaimsIdentity.HasClaim(String type,String   值)在System.Security.Claims.ClaimsPrincipal.IsInRole(String   角色)在System.Security.Principal.WindowsPrincipal.IsInRole(String   角色)   Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement。<> c__DisplayClass4_0.b__0(String   r)位于System.Linq.Enumerable.Any [TSource](IEnumerable 1 source, Func 2谓词)   Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.HandleRequirementAsync(AuthorizationHandlerContext   上下文,请参见RolesAuthorizationRequirement要求)   Microsoft.AspNetCore.Authorization.AuthorizationHandler 1.HandleAsync(AuthorizationHandlerContext context) at Microsoft.AspNetCore.Authorization.Infrastructure.PassThroughAuthorizationHandler.HandleAsync(AuthorizationHandlerContext context) at Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal user, Object resource, IEnumerable 1的要求),网址为   Microsoft.AspNetCore.Components.AuthorizeViewCore.IsAuthorizedAsync(ClaimsPrincipal   用户)   Microsoft.AspNetCore.Components.AuthorizeViewCore.OnParametersSetAsync()   在   Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(任务   任务)   Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

3 个答案:

答案 0 :(得分:1)

根据github上的issue tracker

  

当前,内置的内部默认FixedAuthenticationStateProvider假定其名称所暗示的状态在电路的整个生命周期内都是固定的。但是,这对于Windows身份验证来说是不够的,因为WindowsPrincipal已连接到底层OS服务,并且如果原始HTTP请求已完成,则不能继续使用。如果委托人已经被处置,尝试调用IsInRole之类的东西将会抛出

该修补程序已合并到主版本,并将与asp.net核心 3.0.0-preview8

一起发布。

更新:似乎已解决,see here升级到Preview8并修复重大更改。

答案 1 :(得分:0)

尝试此代码段,看看它是否对您有用:

@attribute [Authorize(Roles = "admin, superuser")]

如果这样做,则意味着您应该使用:

@attribute [Authorize(Roles = "Domain Users")]

请显示您的Startup类的内容

希望这对您有帮助...

答案 2 :(得分:0)

我遇到了同样的问题-Blazor应用程序具有.Net Core 3.0-preview 6。

我正在使用自定义AuthorizationHandler和Identity Framework。尝试使用HandleRequirementAsync读取当前用户名时,在context.User.Identity.Name内抛出错误。