Search code examples
angularasp.net-corewebsocketrxjsjwt

JWT Token Authentication in Angular and the .NET Core Apply policies to Web Socket


I am working on a app project in angular client and net core server that uses WebSocket

I have succesfully implemented generating and validating tokens for standard web api controllers. I want authorization token JWT via apply policies to web socket :

However I also want to validate the token for a WebSocket request which of course won't work with the RequireAuthorization() method .

I have setup my middleware pipeline like this:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("PolicyName", policy => policy.RequireClaim("PolicyName"));
});

builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(base64Secret)),
        ValidateIssuer = false,
        ValidateAudience = false
    };
});

app.UseAuthentication();    
app.UseAuthorization();
app.UserPermissionSetMiddleWare();

and I have setup map WebSocket like this:

app.MapGet("/ws", HandleWebSocket).RequireAuthorization("PolicyName");

in angular client by rxjs :

 this.socket$ = webSocket(`ws://XXXXX/ws?token=${this.token}`);//send validate token that contains 'PolicyName'

but its not working. the request not arrived to HandleWebSocket. (Of course everything works fine without RequireAuthorization)

I want to validate JWT during websocket request from angular to .net core


Solution

  • RequireAuthorization seems not support in websocket request, that why it not working.

    Maybe we can Add HTTP/2 WebSockets support for existing controllers to implement this requirement.

    Here is the sample code.

    public class WebSocketController : ControllerBase
    {
        [Route("/ws")]
        [Authorize(Policy = "PolicyName")] 
        public async Task Get()
        {
            if (HttpContext.WebSockets.IsWebSocketRequest)
            {
                using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
                await Echo(webSocket);
            }
            else
            {
                HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
            }
        }
    }