Reputation: 267
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();
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
Reputation: 267
_hubConnection = new HubConnectionBuilder()
//.WithUrl($"{APIService._apiUrl}/chatt")
.WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
.Build();
options.Headers.Add("Authorization",$"Basic {credential}"))
Upvotes: 4