sasko
sasko

Reputation: 267

connecting to SignalR hub with basic authentication

Hi I am trying to create chat app using xamarin app, .net core api and signalR.
I need to get id of curent user inside of SignalR chatHub.
I tried to get HttpContext by using IHttpContextAccessor but SignalR doesn't support it.
I tried to get HttpContext by Context.GetHttpContext() but it only returns empty Context
(as far as i understand to get current HttpContext with Context.GetHttpContext() project either has to be website or i need to place [Authentication] on my ChatHub )

I am using basic authentication on my project and i don't know how to pass user credentials to SignalR hub

Here is code from Xamarin project ChatViewModel which i use to create new connection to Signalr hub(connection without authentication part works fine)
I don't know how to get curent users email and password instead of "[email protected]" and "123"

  var credential = Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes("[email protected]" + ":" + "123"));
        var con = APIService._Url + "/chatt";
        _hubConnection = new HubConnectionBuilder()
                        //.WithUrl($"{APIService._apiUrl}/chatt")
                        .WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
                        .Build();

Here is my BasicAuthenticationHandler class i use to authenticate users
 public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    private readonly IKorisnikService _userService;
   

    public BasicAuthenticationHandler(
        IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock,
        IKorisnikService userService)
        :base(options, logger, encoder, clock)
    {
        _userService = userService;
       
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (!Request.Headers.ContainsKey("Authorization"))
           return AuthenticateResult.Fail("Missing Authorization Header");

        Restoran.Model.Korisnik user = null;

        try
        {
            var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
            var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
            var credentials = Encoding.UTF8.GetString(credentialBytes).Split(':');
            var username = credentials[0];
            var password = credentials[1];


            user =  _userService.Authenticiraj(username, password);

        }
        catch
        {
            return AuthenticateResult.Fail("Invalid Authorization Header");
        }

        if (user == null)
        {

            return AuthenticateResult.Fail("Invalid Username or Password");


        }

       

        var claims = new List<Claim> {
            new Claim(ClaimTypes.NameIdentifier, user.KorisnikId.ToString()),
            new Claim(ClaimTypes.Name, user.Ime),
        };
        foreach (var role in user.KorisnikUloga)
        {
            claims.Add(new Claim(ClaimTypes.Role, role.Uloga.NazivUloge));
        }

        var identity = new ClaimsIdentity(claims, user.Email);
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, user.Ime);

       

      

        return AuthenticateResult.Success(ticket);
    }
}

I din't include ChatHub code because there is nothing wrong with it and it has only default onConnectedAsync and onDisConnectedAsync methods
Any help is appreciated!!
Thanks for trying to help!!!

Upvotes: 1

Views: 2416

Answers (1)

sasko
sasko

Reputation: 267

_hubConnection = new HubConnectionBuilder()
                    //.WithUrl($"{APIService._apiUrl}/chatt")
                    .WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
                    .Build();

In this line of code needs to be space between basic and {credential} othervise you get incorrect header value
options.Headers.Add("Authorization",$"Basic {credential}"))

Upvotes: 4

Related Questions