Azure Function 中使用 JWT 进行无服务器 SignalR 身份验证

Ror*_*san 3 signalr azure-functions

我正在SignalRConnectionInfoAzure 函数中使用输入绑定。在此绑定中,我需要提供userId当前主体的 ,但默认情况下,Azure 函数仅支持使用应用服务身份验证中的预定义标头,如此处以下示例中所述:

[FunctionName("negotiate")]
public static SignalRConnectionInfo Negotiate(
  [HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req, 
  [SignalRConnectionInfo(HubName = "foo", UserId = "{headers.x-ms-client-principal-id}")] SignalRConnectionInfo connectionInfo)
{
  return connectionInfo;
}
Run Code Online (Sandbox Code Playgroud)

由于我没有使用应用程序服务身份验证,并且不希望这样做,因此这不适合我的需求。

我目前拥有的是一个 JWT,用户将其提供给我们在另一个应用服务中托管的 API,以便对请求进行身份验证并识别自己的身份。如何修改绑定UserId的属性SignalRConnectionInfo以从该 JWT 中的声明中检索 UserId?

Pra*_*SFT 7

AFAIK 没有办法使用绑定表达式从 JWT 中提取信息。

相反,您必须使用运行时绑定首先从 JWT 中提取信息,然后在绑定中使用它来获取 SignalR 连接信息。

下面是一个功能示例,其中从标头检索 JWT Authorization、进行验证,然后将其应用于SignalRConnectionInfo属性。

[FunctionName("Negotiate")]
public static async Task<IActionResult> Run(
  [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "negotiate")] HttpRequest req,
  IBinder binder)
{
  if (!req.Headers.ContainsKey("Authorization"))
    return new UnauthorizedResult();

  var principal = TryGetPrincipal(req.Headers["Authorization"].ToString());
  if (principal == null) 
    return new UnauthorizedResult();

  var connectionInfo = await binder.BindAsync<SignalRConnectionInfo>(new SignalRConnectionInfoAttribute
  {
    HubName = _hubName,
    UserId = principal.FindFirst(ClaimTypes.NameIdentifier).Value
  });
  return new OkObjectResult(connectionInfo);
}

public ClaimsPrincipal TryGetPrincipal(string token) 
{
  // implementation varies based on authorization type...
}
Run Code Online (Sandbox Code Playgroud)