0

My goal is: To use custom headers with my own token to authenticate a user or machine against my signalr service.

We've been using this methodology succesfully under ASP.net WEB API to perform our own custom claims based authentication and authorization.

Our Web Api was as follows:

protected void Application_Start()
{
        GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthorizationHeaderHandler());

}

Then we would have a AuthorizationHandler that would overwrite the Thread.CurrentPrincipal = principal; and we would be done.

Within SignalR I have tried to implement: 1. Mark our hub using Authorize 2. Implemented custom authorize atributes 3. Tried A Custom Module. But besides returning true if the correct headers we're send I still do not get the Context.User to change to the claims based principal that we generate.

But never can we get the Context.User to show the actual user that's being used to connect to the hub.

Any suggestions are Welcome.

Main reason why we want to achieve this is because we have a couple of different user/machine types that connect to our system.

Anybody any suggestions.

CrazyBernie
  • 174
  • 1
  • 8

1 Answers1

2

Finally found the solution.

I added my own owin security middleware allowing me to handle customer header based authentication.

This could be easily expanded allowing you to combine multiple authenitication scheme's within on service.

First Create Custom Authentication Middleware:

public class AuthenticationMiddleware : OwinMiddleware
{
    public AuthenticationMiddleware(OwinMiddleware next) :
        base(next) { }


    public override async Task Invoke(IOwinContext context)
    {
        var request = context.Request;
        var value = request.Headers["Phocabby-MachineKey"];
        var username = value;
        var usernameClaim = new Claim(ClaimTypes.Name, username);
        var identity = new ClaimsIdentity(new[] { usernameClaim }, "ApiKey");
        var principal = new ClaimsPrincipal(identity);
        principal.Identities.First().AddClaim(new Claim("CanGetApiKey", "False"));
        principal.Identities.First().AddClaim(new Claim("Cabinet", "True"));
        request.User = principal;
        await Next.Invoke(context);
    }
}

Then register it in the startup class

public void Configuration(IAppBuilder app)
{
    app.Use(typeof(AuthenticationMiddleware));
    app.MapSignalR();
}
Sam
  • 601
  • 6
  • 22
CrazyBernie
  • 174
  • 1
  • 8
  • After spending many hours fiddling with a custom SignalR authorize attribute, and trying to get my claims in somehow with how we are authenticating, I can confirm your answer works, and at least to me is much simpler. Now I just decorate my hub with the built-in [Authorize] attribute, and it "just works". I wanted to say thanks, but also let others know this general idea for me as well, after modifying the Invoke to suit my needs. – Michael Jan 20 '15 at 19:45