Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SignalR Authentication with Angular #5239

Closed
mgochmuradov opened this issue Aug 31, 2020 · 3 comments
Closed

SignalR Authentication with Angular #5239

mgochmuradov opened this issue Aug 31, 2020 · 3 comments

Comments

@mgochmuradov
Copy link
Contributor

The user is not getting authenticated when using an angular client.

Framework details

  • ABP Framework version : 2.9
  • User Interface: Angular
  • Exception message and stack trace:
2020-08-31 17:03:17.978 +05:00 [INF] Request starting HTTP/1.1 GET https://localhost:44376/signalr-hubs/chatting?id=6hm_mc1QgW6kixUW6sIqWQ&access_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjVlYjg2M2IyNTgxMWE3MDk5ZjliYzkyNWMwZmRmNjgwIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE1OTg4NzMyNDEsImV4cCI6MTYzMDQwOTI0MSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNzYiLCJhdWQiOiJHb2xkYXciLCJjbGllbnRfaWQiOiJHb2xkYXdfQXBwIiwic3ViIjoiNjA5YmM3NTUtYWMwMS1jYzRhLWQ3YjctMzlmNmVmYTU4NTIwIiwiYXV0aF90aW1lIjoxNTk4ODczMjQxLCJpZHAiOiJsb2NhbCIsIm5hbWUiOiJzZXJkYXIiLCJlbWFpbCI6InNlcmRhckBtaW5zdHJveS5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInNjb3BlIjpbIkdvbGRhdyJdLCJhbXIiOlsicHdkIl19.UO7BgxCaJlRWfCMbwwBZ_cuHHFk3u1wwRs0iEkiY3D8ppq9rEmHKpuYWO8BBUmRC7Xj0vAW0XF5L8yHMyhxyEfAdfhj9ESlhLD_PJ1MCeYDuwcvbTDNsW0I4lo8qng58314GjD_zQDEtduqGaL_BlvfbjSZ1b-gWr63iCvzNpQpLg6sWA8rpZGLOGjwblJeh3hcldVut-EwQzcfBQ1pzNrMbPUfFLLQpkHiq2K7YQxylwssVk_H-7kY4-VRbMDpYpPi3pmLJfwTeI7BU0F9MT1RbqjSra6V39bJr3njfVBmQfhqi2w9ubjEO7nxiLVFtDj59qSz9aOTxkSj6jtsCIw  
2020-08-31 17:03:17.979 +05:00 [INF] CORS policy execution successful.
2020-08-31 17:03:17.980 +05:00 [DBG] AuthenticationScheme: Bearer was not authenticated.
2020-08-31 17:03:17.980 +05:00 [DBG] CORS request made for path: /signalr-hubs/chatting from origin: http://localhost:4200 but was ignored because path was not for an allowed IdentityServer CORS endpoint
2020-08-31 17:03:17.980 +05:00 [INF] No CORS policy found for the specified request.
2020-08-31 17:03:17.984 +05:00 [INF] Executing endpoint '/signalr-hubs/chatting'
2020-08-31 17:03:29.008 +05:00 [ERR] Failed to invoke hub method 'Join'.
System.InvalidOperationException: Nullable object must have a value.
   at System.Nullable`1.get_Value()
   at Volo.Abp.Users.CurrentUserExtensions.GetId(ICurrentUser currentUser)
   at Payhas.Goldaw.Chatting.Hubs.ChattingHub.Join()
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.ExecuteHubMethod(ObjectMethodExecutor methodExecutor, THub hub, Object[] arguments)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.<>c__DisplayClass13_0.<<Invoke>g__ExecuteInvocation|0>d.MoveNext()
  • Steps needed to reproduce the problem:
  1. Create a new project with angular UI,
  2. Add SignalR module,
  3. Create a simple hub with method Join() where we use CurrentUser.GetId():
    public class ChattingHub : AbpHub
    {
        public async Task Join()
        {
            CurrentUser.GetId();
        }
    }
  1. In Angular add @aspnet/signalr
  2. Try to connect to signalr hub:
this.hubConnection = new HubConnectionBuilder()
    .withUrl(`${environment.apis.default.url}/signalr-hubs/chatting`,
        { accessTokenFactory: () => this.oAuthService.getAccessToken() })
    .build();
this.hubConnection.invoke('Join');

The problem:

The problem here is that the angular client will send access_token as a query parameter instead of the header.
This is also stated in official documentation: https://docs.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.1
How ever, I am not sure how to apply the workaround.

Not working way:

I have added JwtBearerEvents in Host Module, but that didn't helped

private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
        {
            context.Services.AddAuthentication()
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = configuration["AuthServer:Authority"];
                    options.RequireHttpsMetadata = false;
                    options.ApiName = "Goldaw";
                    options.JwtBearerEvents = new JwtBearerEvents
                    {
                        OnMessageReceived = context =>
                        {
                            var accessToken = context.Request.Query["access_token"];

                            // If the request is for our hub...
                            var path = context.HttpContext.Request.Path;
                            if (!string.IsNullOrEmpty(accessToken) &&
                                (path.StartsWithSegments("/signalr-hubs")))
                            {
                                // Read the token out of the query string
                                context.Token = accessToken;
                            }
                            return Task.CompletedTask;
                        }
                    };
                    options.JwtBackChannelHandler = new HttpClientHandler()
                    {
                        ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                    };
                });
        }

Could you please document required actions to configure SignalR authentication with Angular client, and/or preconfigure authentication in the SignalR module itself?

Thanks!

@maliming
Copy link
Member

maliming commented Sep 1, 2020

hi
You can try add a middleware. and make it have a high priority.

app.Use(async (httpContext, next) =>
{
	var accessToken = httpContext.Request.Query["access_token"];

	var path = httpContext.Request.Path;
	if (!string.IsNullOrEmpty(accessToken) &&
		(path.StartsWithSegments("/signalr-hubs/chat")))
	{
		httpContext.Request.Headers["Authorization"] = "Bearer " + accessToken;
	}

	await next();
});

@mgochmuradov
Copy link
Contributor Author

Yes, it is working now. Thanks!

PS: Also consider adding this to the documentation. This may help others too.

@maliming
Copy link
Member

maliming commented Sep 1, 2020

I think this is related to AddIdentityServerAuthentication method, and we are ready to replace it. see #5247

@maliming maliming closed this as completed Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants