带有websocket和AD身份验证的Azure App Service

时间:2019-07-01 14:18:46

标签: azure signalr azure-active-directory

我们已经将一个应用程序部署为App Service,并且正在使用SignalR进行通信。启用AAD身份验证之后-在浏览器中,我们开始接收302响应,其中包含重定向到Azure AD的位置。

似乎App Service上的身份验证层正在忽略查询字符串传递的access_token

请求

Request URL: wss://<url>/hubs/chat?access_token=<token>
Request Method: GET

响应

Status Code: 302 Redirect
Location: https://login.windows.net/common/oauth2/authorize?...

环顾四周,我们找不到任何解决方案来完成这项工作。 我们看到的唯一解决方案是在App Service上禁用身份验证或使用Long-Pooling,但是在我们的情况下,这两个选项都不可接受。

3 个答案:

答案 0 :(得分:0)

默认情况下,您的Web应用程序不会从查询字符串获取访问令牌。通常,它将从授权标头或cookie中获取访问令牌。

要从查询字符串获取访问令牌,您需要实现自定义身份验证方式。

  1. 安装Microsoft.Owin.Security.ActiveDirectory NuGet软件包。
  2. 创建一个身份验证提供程序,它将从查询字符串获取访问令牌。

public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider { public override Task RequestToken(OAuthRequestTokenContext context) { var value = context.Request.Query.Get("access_token"); if (!string.IsNullOrEmpty(value)) { context.Token = value; } return Task.FromResult<object>(null); } }

  1. 在中添加地图。

app.Map("/yourpath", map => { map.UseWindowsAzureActiveDirectoryBearerAuthentication(new WindowsAzureActiveDirectoryBearerAuthenticationOptions { Provider = new QueryStringOAuthBearerProvider(), Tenant = tenantId, TokenValidationParameters = new TokenValidationParameters { ValidAudience = clientId } }); map.RunSignalR(hubConfiguration); });

答案 1 :(得分:0)

使用自定义中间件,我能够在授权发生之前更新请求:

using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace Stackoverflow.Example.Security.Middleware
{
    public class BearerTokenFromQueryToHeaderMiddleware
    {
        private readonly RequestDelegate _next;

        public BearerTokenFromQueryToHeaderMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var token = context.Request.Query["access_token"];
            if (!string.IsNullOrWhiteSpace(token))
            {
                context.Request.Headers.Add("Authorization", $"Bearer {token}");
            }
            await _next(context);
        }
    }
}

我没有尝试使用OpenID框架,但是我使用自定义策略进行了测试。只要在身份验证之前注册了该中间件,就应在框架在标头中查找令牌之前执行此中间件。

这个周末我将与AAD合作进行POC,但我不想让您等待可能的解决方案。

〜干杯

答案 2 :(得分:0)

在多次致电Microsoft技术支持后,MS确认App Service Authentication层不支持在查询字符串中传递的访问令牌,并且尚无此支持的计划。因此,有两种选择:

  • 对SignalR使用不同的协议(长时间的共享就可以了)
  • Drop App服务身份验证