是否可以使用Azure Active Directory身份验证在本地调试Azure功能? [英] Is it Possible to Debug Azure Functions Locally with Azure Active Directory Authentication?

查看:137
本文介绍了是否可以使用Azure Active Directory身份验证在本地调试Azure功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我整天都在学习Azure Functions的工作方式.我已经在Azure Active Directory中注册了Azure功能,并且已经通过Azure门户中提供的Azure Active Directory对该应用程序进行了注册.

I have been spending the day learning how Azure Functions work. I have gotten my Azure Function registered with my Azure Active Directory, and have registered this application to be secured by way of my Azure Active Directory provide in my Azure Portal.

我已将其部署到Azure,并且一切正常,要求我的Azure AD用户帐户,并且一旦登录,就可以按我的期望向我显示我的HelloWorld Azure功能.

I have deployed this to Azure and everything works as expected, asking for my Azure AD User account, and once I sign in it shows me my HelloWorld Azure Function as I expect.

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

Additionally, I have been able to debug my Azure Function locally. However, locally it is using the AuthorizationLevel as configured on my HttpTriggerAttribute (AuthorizationLevel.Anonymous).

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

This, of course, is ignored when deployed in Azure, but locally now I have lost my user identity as it is configured to be anonymous and not using Azure Active Directory.

是否可以在本地部署的Azure功能上启用Azure Active Directory身份验证?

Is there a way to enable Azure Active Directory authentication on my locally deployed Azure Function?

这里要清楚一点,我想像使用已部署的Azure函数一样在本地使用Azure函数登录(因此我将被重定向到login.microsoftonline.com进行登录),但是具有相同的身份可用于我的本地Azure Function开发环境.

To be clear here, I would like to sign in with my Azure Function locally just as I do with my deployed Azure Function (so I will be redirected to login.microsoftonline.com to login), but have that same identity be available to my local Azure Function development environment.

感谢您提供的任何帮助!

Thank you for any assistance you can provide!

推荐答案

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

Alright after a few more (OK, a LOT) hours, I have figured out a solution for now. This works in both local and deployed scenarios. I have posted a template solution here:

https://github.com/Mike-EEE/Stash/树/主/AzureV2Authentication/AzureV2Authentication

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

Here are the steps that outline the overall process:

  1. 通过https://function-name .azurewebsites.net
  2. 登录到您的函数
  3. 在Chrome中按CTRL-SHIFT-C->应用程序-> Cookies->-> AppServiceAuthSession->复制值
  4. 打开local.settings.json并粘贴AuthenticationToken设置中上一步的值.
  5. 您在哪里,粘贴第一步AuthenticationBaseAddress
  6. 中的URL
  7. 启动应用程序.
  8. 十指交叉.
  9. 享受魔术(希望如此)
  1. Sign into your function at https://function-name.azurewebsites.net
  2. CTRL-SHIFT-C in Chrome -> Application -> Cookies -> -> AppServiceAuthSession -> Copy Value
  3. Open local.settings.json and paste value from previous step in AuthenticationToken setting.
  4. While you're there, paste in the URL from first step in AuthenticationBaseAddress
  5. Launch application.
  6. Cross fingers.
  7. Enjoy magic (Hopefully.)

这是主要事件:

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. 示例代码基于@stuartleeks的 EasyAuth示例
  3. 该解决方案利用了出色的 Refit 项目来获取其数据.
  1. An HttpClient is created for each call. This is against best practices.
  2. Sample code is based on EasyAuth sample by @stuartleeks
  3. This solution makes use of the excellent Refit project to get its data.

为完整起见,这里是剩下的感兴趣的类别:

Here are the remaining classes of interest, for the sake of completeness:

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 Active Directory身份验证在本地调试Azure功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆