SignalR Authorize attribute not called

780 views Asked by At

I have a hub that does not convert the token located at Authorization:Bearer eyjsdalfsadlfjffdafs... in the request header to an identity. The rest of the API works fine with standard http verbs however for some reason SignalR is not authorizing the token into a user.

public class ChatHub : Hub
{
   [Authorize]
    public override Task OnConnected()
    {
         // error context.user.identity.name =""
        var userId = int.Parse(Context.User.Identity.Name); 


        return base.OnConnected();
    }
....
}

Startup.cs

    public class Startup
{
    public void Configuration(IAppBuilder app)
    {
  app.MapSignalR(); 


    }
}

JwtHandler - this part of the filter is not called when the client connects to the hub even though onConnect() is attributed with [Authorize]

  public class JwtHandler : DelegatingHandler
{
    private const string ISSUER = "Issuer";
    private const string AUDIENCE = "Audience";          
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        byte[] key = Convert.FromBase64String("SecretKey");
        try
        {
            var headers = request.Headers;
            if(headers.Authorization != null)
            {
                if(headers.Authorization.Scheme.Equals("Bearer"))
                {
                    string jwt = request.Headers.Authorization.Parameter;
                    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
                    TokenValidationParameters parms = new TokenValidationParameters()
                    {
                        ValidAudience = AUDIENCE,
                        ValidIssuers = new List<string>(){ISSUER},
                        IssuerSigningToken = new BinarySecretSecurityToken(key),

                    };
                    SecurityToken validated = new JwtSecurityToken(jwt);

                    var principal = tokenHandler.ValidateToken(jwt, parms,out validated);
                    Thread.CurrentPrincipal = principal;

                    if(HttpContext.Current !=null)
                    {
                        HttpContext.Current.User = principal;
                    }

                }

            } 
            var response = await base.SendAsync(request, cancellationToken);
                if(response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "error=\"invalid_token\""));
                    return response;
                }
                return response;
        }catch (Exception)
        {
            var response = request.CreateResponse(HttpStatusCode.Unauthorized);
            response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "error=\"invalid_token\""));
            return response;
        }
       }
 }
1

There are 1 answers

0
cangosta On

Try validating the jwt token in the OWIN middleware. In your Startup.cs add:

public void Configuration(IAppBuilder app)
{
  app.UseJwtBearerAuthentication(
     new Microsoft.Owin.Security.Jwt.JwtBearerAuthenticationOptions() {
        AllowedAudiences = new string[] { ALLOWEDAUDIENCE },
        IssuerSecurityTokenProviders = new[] { 
                    new SymmetricKeyIssuerSecurityTokenProvider(ISSUER, System.Convert.FromBase64String(cKey)) 
     }
  });
  app.MapSignalR(); 
}