azure - 是否可以使用 Azure Active Directory 身份验证在本地调试 Azure Functions?

标签 azure azure-active-directory azure-functions

我花了一天时间学习 Azure Functions 的工作原理。我已将我的 Azure Function 注册到我的 Azure Active Directory,并已注册此应用程序以通过我的 Azure 门户中的 Azure Active Directory 提供保护。

我已将其部署到 Azure,一切都按预期运行,要求提供我的 Azure AD 用户帐户,一旦我登录,它就会按照我的预期显示我的 HelloWorld Azure 函数。

此外,我已经能够在本地调试我的 Azure Functions。但是,在本地,它使用我的 HttpTriggerAttribute 上配置的 AuthorizationLevel (AuthorizationLevel.Anonymous)。

当然,在 Azure 中部署时会忽略这一点,但现在我在本地丢失了我的用户身份,因为它配置为匿名且不使用 Azure Active Directory。

有没有办法在本地部署的 Azure Function 上启用 Azure Active Directory 身份验证?

需要明确的是,我想在本地使用我的 Azure Function 登录,就像使用部署的 Azure Function 一样(因此我将被重定向到 login.microsoftonline.com 进行登录) ,但具有相同的身份可用于我的本地 Azure Function 开发环境。

感谢您提供的任何帮助!

最佳答案

好吧,又过了几个(好吧,很多)小时,我现在已经找到了解决方案。这适用于本地和部署场景。我在这里发布了一个模板解决方案:

https://github.com/Mike-E-angelo/Stash/tree/master/AzureV2Authentication/AzureV2Authentication

以下是概述整个过程的步骤:

  1. 通过 https://function-name.azurewebsites.net 登录您的函数
  2. Chrome 中的 CTRL-SHIFT-C -> 应用程序 -> Cookie -> -> AppServiceAuthSession -> 复制值
  3. 打开 local.settings.json 并将上一步中的值粘贴到 AuthenticationToken 设置中。
  4. 当您在那里时,将第一步中的网址粘贴到 AuthenticationBaseAddress
  5. 启动应用程序。
  6. 交叉手指。
  7. 享受魔法(希望如此。)

主要事件如下:

public static class AuthenticationExtensions
{
    public static Authentication Authenticate(this HttpRequest @this)
    {
        var handler = new HttpClientHandler();
        var client = new HttpClient(handler) // Will want to make this a singleton.  Do not use in production environment.
        {
            BaseAddress = new Uri(Environment.GetEnvironmentVariable("AuthenticationBaseAddress") ?? new Uri(@this.GetDisplayUrl()).GetLeftPart(UriPartial.Authority))
        };
        handler.CookieContainer.Add(client.BaseAddress, new Cookie("AppServiceAuthSession", @this.Cookies["AppServiceAuthSession"] ?? Environment.GetEnvironmentVariable("AuthenticationToken")));

        var service = RestService.For<IAuthentication>(client);

        var result = service.GetCurrentAuthentication().Result.SingleOrDefault();
        return result;
    }
}

请注意:

  1. 为每个调用创建一个 HttpClient。这违反了最佳实践。
  2. 示例代码基于 EasyAuth sample by @stuartleeks
  3. 此解决方案利用了出色的 Refit项目来获取其数据。

为了完整起见,以下是剩余的感兴趣的类别:

public class Authentication // structure based on sample here: https://cgillum.tech/2016/03/07/app-service-token-store/
{
    [JsonProperty("access_token", NullValueHandling = NullValueHandling.Ignore)]
    public string AccessToken { get; set; }
    [JsonProperty("provider_name", NullValueHandling = NullValueHandling.Ignore)]
    public string ProviderName { get; set; }
    [JsonProperty("user_id", NullValueHandling = NullValueHandling.Ignore)]
    public string UserId { get; set; }
    [JsonProperty("user_claims", NullValueHandling = NullValueHandling.Ignore)]
    public AuthenticationClaim[] UserClaims { get; set; }
    [JsonProperty("access_token_secret", NullValueHandling = NullValueHandling.Ignore)]
    public string AccessTokenSecret { get; set; }
    [JsonProperty("authentication_token", NullValueHandling = NullValueHandling.Ignore)]
    public string AuthenticationToken { get; set; }
    [JsonProperty("expires_on", NullValueHandling = NullValueHandling.Ignore)]
    public string ExpiresOn { get; set; }
    [JsonProperty("id_token", NullValueHandling = NullValueHandling.Ignore)]
    public string IdToken { get; set; }
    [JsonProperty("refresh_token", NullValueHandling = NullValueHandling.Ignore)]
    public string RefreshToken { get; set; }
}
public class AuthenticationClaim
{
    [JsonProperty("typ")]
    public string Type { get; set; }
    [JsonProperty("val")]
    public string Value { get; set; }
}
interface IAuthentication
{
    [Get("/.auth/me")]
    Task<Authentication[]> GetCurrentAuthentication();
}
public static class Function1
{
    [FunctionName("Function1")]
    public static IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
    {
        log.Info("C# HTTP trigger function processed a request.");

        var authentication = req.Authenticate();

        return authentication != null
            ? (ActionResult)new OkObjectResult($"Hello, {authentication.UserId}")
            : new BadRequestObjectResult("Authentication not found. :(");
    }
}

关于azure - 是否可以使用 Azure Active Directory 身份验证在本地调试 Azure Functions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49390877/

相关文章:

Azure Log Analytics - 更新/添加 FunctioAlias 到 SavedSearch 查询

python - 如何在 Azure 数据工厂 - Databricks 中使用 continuation_token 获取 ADF Pipeline 运行详细信息的下一页?

azure - 如何在 Cosmos DB 中的单个存储过程中执行多个操作

python - 如何将 .parquet 文件从本地计算机上传到 Azure Storage Data Lake Gen2?

python - 在 Azure AD 中创建用户需要哪些应用程序权限?

c# - 从函数应用加载并执行 Azure Blob 容器中的代码?

python - 加载 Python 3.8 Azure Function 的 azure-cosmos 库时出现问题

python - Python Azure 函数的出站 IP - 请求 IP 与函数出站 IP 列表不匹配

c# - 自动续订 Azure 身份验证的最佳方法是什么?

python - 使用 Azure AD 保护 Python Rest API