Open Closed

AzureSignalR setup - claims null reference exception #6717


User avatar
0
dhill created
  • ABP Framework version: v8.0.3
  • UI Type: Blazor Server
  • Database System: EF Core
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: [22:23:24 INF] Starting transport. Transfer mode: Binary. Url: 'wss://[redacted].net/server/?hub=componenthub&cid=b826b8b2-f61a-4eca-aceb-570d28b1beea'. [22:23:24 INF] Now listening on: https://localhost:44354 [22:23:24 INF] Application started. Press Ctrl+C to shut down. [22:23:24 INF] Hosting environment: Development [22:23:24 INF] Content root path: C:\source\SafetyPlusWeb-ABP-App\src\SafetyPlusWeb.Blazor [22:23:24 INF] Service connection b754b5d0-3341-455f-a53a-c35e4b99badd connected. [22:23:24 INF] Service connection b0e6ab7c-ab87-418c-b7e8-571e49128571 connected. [22:23:24 INF] Service connection 1eefadc0-d1f9-4b40-8ade-7036c804dd48 connected. [22:23:24 INF] Service connection b826b8b2-f61a-4eca-aceb-570d28b1beea connected. [22:23:24 INF] Service connection e6d301b3-dec9-4f2b-bb98-04f2fac7a3b7 connected. [22:23:24 INF] Service connection 67b14799-a667-4605-9b09-e935d11b66d0 connected. [22:23:24 INF] Service connection 590415e4-9ade-4d06-991e-7d230b12fa90 connected. [22:23:24 INF] Service connection 55026f85-f28c-48bb-aaf5-6540b7be5bcd connected. [22:23:24 INF] Service connection 4a5f4738-d8fa-4f09-88cd-0c8109fbcbb8 connected. [22:23:24 INF] Service connection 998eadd8-103a-4566-889d-7c58bc258adc connected. [22:23:24 INF] Hub 'ComponentHub' is now connected to '(Primary)https://[redacted].net(hub=ComponentHub)'. [22:23:24 INF] Hub 'Chat' is now connected to '(Primary)https://[redacted].net(hub=Chat)'. [22:23:25 INF] Request starting HTTP/2 GET https://localhost:44354/ - null null [22:23:26 DBG] The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessRequestContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ResolveRequestUri. [22:23:26 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ResolveRequestUri. [22:23:26 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.OpenIddictServerHandlers+InferEndpointType. [22:23:26 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by Volo.Abp.Account.Web.Pages.Account.OpenIddictImpersonateInferEndpointType. [22:23:26 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ValidateTransportSecurityRequirement. [22:23:26 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ValidateHostHeader. [22:23:27 DBG] Get dynamic claims cache for user: 1b711166-ebd0-3844-d68c-3a10b547d0e1 [22:23:27 DBG] Filling dynamic claims cache for user: 1b711166-ebd0-3844-d68c-3a10b547d0e1 [22:23:30 INF] Executing endpoint '/_Host' [22:23:30 INF] Route matched with {page = "/_Host", area = "", action = "", controller = ""}. Executing page /_Host [22:23:30 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy [22:23:30 INF] Executing an implicit handler method - ModelState is Valid [22:23:30 INF] Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult. [22:23:30 DBG] Added bundle 'Blazor.LeptonXTheme.Global' to the page in 27.18 ms. [22:23:30 DBG] Added bundle 'Blazor.LeptonXTheme.Global' to the page in 21.59 ms. [22:23:30 INF] Executed page /_Host in 295.7205ms [22:23:30 INF] Executed endpoint '/_Host' [22:23:30 INF] Request starting HTTP/2 GET https://localhost:44354/_framework/aspnetcore-browser-refresh.js - null null [22:23:30 INF] Request finished HTTP/2 GET https://localhost:44354/ - 200 null text/html; charset=utf-8 5275.9564ms [22:23:30 INF] Request finished HTTP/2 GET https://localhost:44354/_framework/aspnetcore-browser-refresh.js - 200 13776 application/javascript; charset=utf-8 15.3575ms [22:23:30 INF] Request starting HTTP/2 GET https://localhost:44354/_vs/browserLink - null null [22:23:30 INF] Request starting HTTP/2 GET https://localhost:44354/_blazor/initializers - null null [22:23:30 DBG] The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessRequestContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ResolveRequestUri. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ResolveRequestUri. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.OpenIddictServerHandlers+InferEndpointType. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by Volo.Abp.Account.Web.Pages.Account.OpenIddictImpersonateInferEndpointType. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ValidateTransportSecurityRequirement. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ValidateHostHeader. [22:23:30 INF] Request finished HTTP/2 GET https://localhost:44354/_vs/browserLink - 200 null text/javascript; charset=UTF-8 86.6061ms [22:23:30 DBG] Get dynamic claims cache for user: 1b711166-ebd0-3844-d68c-3a10b547d0e1 [22:23:30 INF] Executing endpoint 'Blazor initializers' [22:23:30 INF] Executed endpoint 'Blazor initializers' [22:23:30 INF] Request finished HTTP/2 GET https://localhost:44354/_blazor/initializers - 200 null application/json; charset=utf-8 94.4373ms [22:23:30 INF] Request starting HTTP/2 POST https://localhost:44354/_blazor/negotiate?negotiateVersion=1 - null 0 [22:23:30 DBG] The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessRequestContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ResolveRequestUri. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ResolveRequestUri. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.OpenIddictServerHandlers+InferEndpointType. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by Volo.Abp.Account.Web.Pages.Account.OpenIddictImpersonateInferEndpointType. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ValidateTransportSecurityRequirement. [22:23:30 DBG] The event OpenIddict.Server.OpenIddictServerEvents+ProcessRequestContext was successfully processed by OpenIddict.Server.AspNetCore.OpenIddictServerAspNetCoreHandlers+ValidateHostHeader. [22:23:30 DBG] Get dynamic claims cache for user: 1b711166-ebd0-3844-d68c-3a10b547d0e1 [22:23:30 INF] Executing endpoint '/_blazor/negotiate' [22:23:30 INF] Use default handshake timeout. [22:23:30 INF] Executed endpoint '/_blazor/negotiate' [22:23:30 ERR] An unhandled exception has occurred while executing the request. System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Azure.SignalR.NegotiateHandler1.BuildClaims(HttpContext context) at Microsoft.Azure.SignalR.NegotiateHandler1.Process(HttpContext context) at Microsoft.Azure.SignalR.ServiceRouteHelper.RedirectToService[THub](HttpContext context, IList1 authorizationData) at Microsoft.Azure.SignalR.NegotiateMatcherPolicy.<>c__71.<b__7_0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger) at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Volo.Abp.AspNetCore.Security.Claims.AbpDynamicClaimsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>c__DisplayClass0_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context) [22:23:30 INF] Request finished HTTP/2 POST https://localhost:44354/_blazor/negotiate?negotiateVersion=1 - 500 null text/plain; charset=utf-8 142.9569ms
  • Steps to reproduce the issue:

Trying to add AzureSignalR by following these articles https://support.abp.io/QA/Questions/2054/Using-Azure-SignalR-backplane-for-abp-Blazor-app https://support.abp.io/QA/Questions/4993/Issue-Implementing-Azure%27s-Managed-SignalR-service-with-an-ABP-Blazor-Server-application

Current configuration

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var hostingEnvironment = context.Services.GetHostingEnvironment();
        var configuration = context.Services.GetConfiguration();

        context.Services.AddSignalR(options =>
        {
            options.AddFilter<AbpMultiTenantHubFilter>();
        })
        .AddAzureSignalR(options =>
        {
            options.ServerStickyMode = Microsoft.Azure.SignalR.ServerStickyMode.Required;
            options.ClaimsProvider = context => new[]
            {
            new Claim(ClaimTypes.NameIdentifier, "testing123")
        };
            options.ConnectionString = "Endpoint=[redacted]";
        });
       .......
 }

public class AbpMultiTenantHubFilter : IHubFilter
{
    public virtual async ValueTask<object?> InvokeMethodAsync(HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object?>> next)
    {
        var currentPrincipalAccessor = invocationContext.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
        if (invocationContext.Context.User == null)
            throw new NullReferenceException(nameof(invocationContext.Context.User));
        
        using (currentPrincipalAccessor.Change(invocationContext.Context.User))
        {
            var tenantId = currentPrincipalAccessor.Principal.FindTenantId();
            string? tenantName = null;
            if (tenantId != null)
            {
                tenantName = (await invocationContext.ServiceProvider.GetRequiredService<ITenantStore>().FindAsync(tenantId.Value))?.Name;
            }
            using (invocationContext.ServiceProvider.GetRequiredService<ICurrentTenant>().Change(currentPrincipalAccessor.Principal.FindTenantId(), tenantName))
            {
                return await next(invocationContext);
            }
        }
    }

    public virtual Task OnConnectedAsync(HubLifetimeContext context, Func<HubLifetimeContext, Task> next)
    {
        return Task.CompletedTask;
    }

    public virtual Task OnDisconnectedAsync(HubLifetimeContext context, Exception? exception, Func<HubLifetimeContext, Exception, Task> next)
    {
        return Task.CompletedTask;
    }
}

6 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share a simple project to reproduce?

    liming.ma@volosoft.com

    Thanks

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    This seems to be a problem with https://github.com/Azure/azure-signalr.

    But you can try the code below to fix it.

    app.UseAuthorization();
    
    app.Use(async (httpContext, next) =>
    {
        var authenticateResultFeature = httpContext.Features.Get<IAuthenticateResultFeature>();
        if (authenticateResultFeature != null && authenticateResultFeature.AuthenticateResult == null)
        {
            if (httpContext.User.Identity?.IsAuthenticated == true)
            {
                authenticateResultFeature.AuthenticateResult = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, httpContext.User.Identity.AuthenticationType!));
            }
        }
    
        await next(httpContext);
    });
    
    app.UseSwagger();
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Follow: https://github.com/Azure/azure-signalr/pull/1918

  • User Avatar
    0
    dhill created

    Getting this error after implementing as suggested.

    This exception was originally thrown at this call stack: [External Code] AzureSignalRPoc.Blazor.AzureSignalRPocBlazorModule.OnApplicationInitialization.AnonymousMethod__16_0(Microsoft.AspNetCore.Http.HttpContext, Microsoft.AspNetCore.Http.RequestDelegate) in AzureSignalRPocBlazorModule.cs

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var env = context.GetEnvironment();
        var app = context.GetApplicationBuilder();
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseAbpRequestLocalization();
    
        if (!env.IsDevelopment())
        {
            app.UseErrorPage();
            app.UseHsts();
        }
    
        app.UseCorrelationId();
        app.UseAbpSecurityHeaders();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAbpOpenIddictValidation();
    
        if (MultiTenancyConsts.IsEnabled)
        {
            app.UseMultiTenancy();
        }
    
        app.Use(async (httpContext, next) =>
        {
            var authenticateResultFeature = httpContext.Features.Get&lt;IAuthenticateResultFeature&gt;();
            if (authenticateResultFeature != null && authenticateResultFeature.AuthenticateResult == null)
            {
                if (httpContext.User.Identity?.IsAuthenticated == true)
                {
                    authenticateResultFeature.AuthenticateResult = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, httpContext.User.Identity.AuthenticationType!));
                }
            }
    
            await next(httpContext);
        });
    
        app.UseUnitOfWork();
        app.UseDynamicClaims();
        app.UseAuthorization();
        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "AzureSignalRPoc API");
        });
        app.UseAuditing();
        app.UseAbpSerilogEnrichers();
        app.UseConfiguredEndpoints();
    }
    

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Please change your OnApplicationInitialization method by follow:

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var env = context.GetEnvironment();
        var app = context.GetApplicationBuilder();
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseAbpRequestLocalization();
    
        if (!env.IsDevelopment())
        {
            app.UseErrorPage();
            app.UseHsts();
        }
    
        app.UseCorrelationId();
        app.UseAbpSecurityHeaders();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAbpOpenIddictValidation();
    
        if (MultiTenancyConsts.IsEnabled)
        {
            app.UseMultiTenancy();
        }
    
        app.UseUnitOfWork();
        app.UseDynamicClaims();
        app.UseAuthorization();
    
        app.Use(async (httpContext, next) =>
        {
            var authenticateResultFeature = httpContext.Features.Get<IAuthenticateResultFeature>();
            if (authenticateResultFeature != null && authenticateResultFeature.AuthenticateResult == null)
            {
                if (httpContext.User.Identity?.IsAuthenticated == true)
                {
                    authenticateResultFeature.AuthenticateResult = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, httpContext.User.Identity.AuthenticationType!));
                }
            }
    
            await next(httpContext);
        });
    
        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "AzureSignalRPoc API");
        });
        app.UseAuditing();
        app.UseAbpSerilogEnrichers();
        app.UseConfiguredEndpoints();
    }
    
  • User Avatar
    0
    dhill created

    Hi maliming,

    That last change you suggested was the solution. Everything appears to be working now.

    Right now I have that code in OnApplicationInitialization and these settings in appsettings.json

    "Azure": { "SignalR": { "Enabled": "true" } }

    { "Azure:SignalR:ConnectionString": "Endpoint=https://xxxxxxx.service.signalr.net;AccessKey=xxxxxxxxxx=;Version=1.0;" }

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11