在Asp.Net核心Web应用程序中使用EasyAuth对Azure App Service上的AAD进行身份验证时,无法填充ClaimsPrincipal

时间:2017-01-06 08:17:48

标签: authentication asp.net-core azure-web-sites azure-active-directory

我们有一个基于Asp.Net核心的网络应用程序。它不包含在其中配置的任何身份验证中间件。

我们托管Azure App Service并使用身份验证/授权选项(EasyAuth)对Azure AD进行身份验证。

身份验证效果很好 - 我们插入了必需的标头,我们可以在/.auth/me上看到经过身份验证的身份。但是HttpContext.User属性并没有被填充。

这是Asp.Net核心的兼容性问题吗?或者我做错了什么?

5 个答案:

答案 0 :(得分:11)

是的,这是一个兼容性问题。不幸的是,ASP.NET Core不支持从IIS模块(如Easy Auth)流向身份信息到应用程序代码。这意味着HttpContext.User和类似的代码不像常规ASP.NET一样工作。

现在的解决方法是从服务器代码调用您的Web应用程序的/.auth/me端点以获取用户声明。然后,您可以使用x-ms-client-principal-id请求标头值作为缓存密钥,根据需要缓存此数据。 /.auth/me调用需要进行适当的身份验证,方法与调用Web应用程序需要进行身份验证的方式相同(auth cookie或request header token)。

答案 1 :(得分:10)

我创建了一个自定义中间件来填充User属性,直到Azure团队解决了这个问题。

它从应用服务身份验证中读取标头,并创建一个将被copy识别并在[Authorize]上声明的用户。

name

答案 2 :(得分:5)

我写了一个小的基本中间件来做到这一点。它将基于.auth / me端点创建一个标识。身份在身份验证管道中创建,以便[authorize]属性和策略与身份一起使用。

你可以在这里找到它:

https://github.com/lpunderscore/azureappservice-authentication-middleware

或nuget:

https://www.nuget.org/packages/AzureAppserviceAuthenticationMiddleware/

添加后,只需将此行添加到您的启动中:

app.UseAzureAppServiceAuthentication();

答案 3 :(得分:2)

以下代码从Azure App Service HTTP标头解密AAD令牌,并使用声明填充HttpContext.User。这很粗糙,因为您想要缓存配置而不是在每次请求时查找:

    OpenIdConnectConfigurationRetriever r = new OpenIdConnectConfigurationRetriever();
    ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(options.Endpoint, r);
    OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync();

    var tokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKeys = config.SigningKeys.ToList(),
        ValidateIssuer = true,
        ValidIssuer = config.Issuer,
        ValidateAudience = true,
        ValidAudience = options.Audience,
        ValidateLifetime = true,
        ClockSkew = new TimeSpan(0, 0, 10)
    };

    JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();

    ClaimsPrincipal principal = null;
    SecurityToken validToken = null;

    string token = context.Request.Headers["X-MS-TOKEN-AAD-ID-TOKEN"];

    if (!String.IsNullOrWhiteSpace(token))
    {
        principal = handler.ValidateToken(token, tokenValidationParameters, out validToken);

        var validJwt = validToken as JwtSecurityToken;

        if (validJwt == null) { throw new ArgumentException("Invalid JWT"); }

        if (principal != null)
        {
            context.User.AddIdentities(principal.Identities);
        }
    }

它仅适用于Azure AD。为了支持其他ID提供商(Facebook,Twitter等),您必须检测相关标头并找出如何解析每个提供商的令牌。但是,它应该只是上述主题的变体。

答案 4 :(得分:0)

您可以尝试使用此库。我遇到了类似的问题,并创建了这个问题以简化使用。

https://github.com/dasiths/NEasyAuthMiddleware

  

用于ASP.NET的Azure App Service身份验证(EasyAuth)中间件   具有完全可定制组件的CORE,并支持本地   调试

它通过注册自定义身份验证处理程序来补充HttpContext.User。为了使在本地运行时更容易,它甚至可以使用json文件加载模拟的声明。