是否可以使用Azure Active Directory身份验证在本地调试Azure功能?

时间:2018-03-20 17:41:23

标签: azure azure-active-directory azure-functions

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

我已经将此部署到Azure,一切都按预期工作,要求我的Azure AD用户帐户,一旦我登录,它就像我期望的那样向我显示我的HelloWorld Azure功能。

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

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

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

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

感谢您提供任何帮助!

2 个答案:

答案 0 :(得分:4)

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

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

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

  1. 使用https:// function-name .azurewebsites.net
  2. 登录您的功能
  3. Chrome中的CTRL-SHIFT-C - >申请 - > Cookies - > - > AppServiceAuthSession - >复制值
  4. 打开local.settings.json并粘贴AuthenticationToken设置中上一步的值。
  5. 当您在那里时,请粘贴AuthenticationBaseAddress
  6. 中第一步的网址
  7. 启动应用程序。
  8. 交叉手指。
  9. 享受魔力(希望。)
  10. 这是主要事件:

    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项目来获取其数据。
    4. 为了完整起见,以下是其余感兴趣的课程:

      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. :(");
          }
      }
      

答案 1 :(得分:3)

Here is another alternative(如果您正在开发带有JWT令牌的SPA,并通过Easy Auth使用Azure-AD或Azure B2C。