我们已经将一个应用程序部署为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,但是在我们的情况下,这两个选项都不可接受。
答案 0 :(得分:0)
默认情况下,您的Web应用程序不会从查询字符串获取访问令牌。通常,它将从授权标头或cookie中获取访问令牌。
要从查询字符串获取访问令牌,您需要实现自定义身份验证方式。
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);
}
}
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层不支持在查询字符串中传递的访问令牌,并且尚无此支持的计划。因此,有两种选择: