使用基本身份验证连接到 SignalR hub
connecting to SignalR hub with basic authentication
您好,我正在尝试使用 xamarin 应用程序、.net 核心 api 和 signalR 创建聊天应用程序。
我需要在 SignalR chatHub 中获取当前用户的 ID。
我尝试使用 IHttpContextAccessor 获取 HttpContext,但 SignalR 不支持它。
我试图通过 Context.GetHttpContext() 获取 HttpContext 但它只有 returns empty Context
(据我所知,要使用 Context.GetHttpContext() 项目获取当前的 HttpContext,要么必须是网站,要么我需要放置 [Authentication] 在我的 ChatHub 上)
我在我的项目上使用基本身份验证,但我不知道如何将用户凭据传递给 SignalR hub
这是 Xamarin 项目 ChatViewModel 的代码,我用它来创建
与 Signalr hub 的新连接(没有身份验证部分的连接工作正常)
我不知道如何获取当前用户的电子邮件和密码而不是“email@hotmail.com”和“123” "
var credential = Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes("email@hotmail.com" + ":" + "123"));
var con = APIService._Url + "/chatt";
_hubConnection = new HubConnectionBuilder()
//.WithUrl($"{APIService._apiUrl}/chatt")
.WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
.Build();
这是我用来验证用户身份的 BasicAuthenticationHandler class
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);
}
}
我没有包含 ChatHub 代码,因为它没有任何问题,它只有默认的 onConnectedAsync 和 onDisConnectedAsync 方法
感谢任何帮助!!
感谢您的帮助!!!
_hubConnection = new HubConnectionBuilder()
//.WithUrl($"{APIService._apiUrl}/chatt")
.WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
.Build();
在这行代码中,需要在 basic 和 {credential} 之间 space 否则你会得到不正确的 header value
options.Headers.Add("Authorization",$"Basic {credential}"))
您好,我正在尝试使用 xamarin 应用程序、.net 核心 api 和 signalR 创建聊天应用程序。
我需要在 SignalR chatHub 中获取当前用户的 ID。
我尝试使用 IHttpContextAccessor 获取 HttpContext,但 SignalR 不支持它。
我试图通过 Context.GetHttpContext() 获取 HttpContext 但它只有 returns empty Context
(据我所知,要使用 Context.GetHttpContext() 项目获取当前的 HttpContext,要么必须是网站,要么我需要放置 [Authentication] 在我的 ChatHub 上)
我在我的项目上使用基本身份验证,但我不知道如何将用户凭据传递给 SignalR hub
这是 Xamarin 项目 ChatViewModel 的代码,我用它来创建
与 Signalr hub 的新连接(没有身份验证部分的连接工作正常)
我不知道如何获取当前用户的电子邮件和密码而不是“email@hotmail.com”和“123” "
var credential = Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes("email@hotmail.com" + ":" + "123"));
var con = APIService._Url + "/chatt";
_hubConnection = new HubConnectionBuilder()
//.WithUrl($"{APIService._apiUrl}/chatt")
.WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
.Build();
这是我用来验证用户身份的 BasicAuthenticationHandler class
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);
}
}
我没有包含 ChatHub 代码,因为它没有任何问题,它只有默认的 onConnectedAsync 和 onDisConnectedAsync 方法
感谢任何帮助!!
感谢您的帮助!!!
_hubConnection = new HubConnectionBuilder()
//.WithUrl($"{APIService._apiUrl}/chatt")
.WithUrl(con, options=> options.Headers.Add("Authorization",$"Basic{credential}"))
.Build();
在这行代码中,需要在 basic 和 {credential} 之间 space 否则你会得到不正确的 header value
options.Headers.Add("Authorization",$"Basic {credential}"))