如何使用Azure身份验证在Azure函数中获取当前用户身份?

weylhg0b  于 2023-06-24  发布在  其他
关注(0)|答案(6)|浏览(147)

我已经创建了一个新的功能应用程序,启用了应用程序服务身份验证/授权(“* 使用身份验证/授权来保护您的应用程序并处理每个用户的数据 *”),并禁用了未经身份验证的请求。
到目前为止,一切似乎都正常工作。如果我尝试请求我的HttpTrigger艾德函数,它要求我先登录;一旦我登录,所有请求都将按正常方式处理。所以“保护您的应用程序”部分没有问题。
然而,我完全被“处理每用户数据”这部分卡住了。我的Azure函数被调用为

public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)

HttpRequestMessage中没有任何与身份验证相关的内容。(AuthorizationLevel.Anonymous似乎控制着完全不同的事情--也就是说,函数是否可以被任何人调用,或者只能被那些拥有固定API密钥的人调用)。
如何获取调用该函数的已验证用户的身份?

qnzebej0

qnzebej01#

使用Azure Function runtime v2.0.12309,您可以从Run方法中注入的ClaimsPrincipal示例中检索authenticated user information

public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]
    HttpRequest httpRequest, 
    ILogger logger, 
    ClaimsPrincipal claimsPrincipal)
 {
            // Explores the authenticated user's claims in claimsPrincipal.
 }
mepcadol

mepcadol2#

从逻辑上讲,AuthorizationLevel.Anonymous * 不会为您提供当前索赔本金 *。
不幸的是,仅仅更改为AuthorizationLevel.Function也没有帮助:对我来说,我发现ClaimsPrincipal.Current为null,即使在通过Azure Active Directory B2C成功进行身份验证后也是如此。
最后,我尝试了AuthorizationLevel.User,但azure函数目前不支持它(请参阅here
我相信你需要按照this SO question上接受的答案的步骤(我现在正在尝试...)

3phpmpom

3phpmpom3#

似乎可以从全局状态System.Security.Claims.ClaimsPrincipal.Current.Identity.Name获取当前用户名(我最初发布这个问题时并不知道)。然而,目前还不清楚这是否是一种可靠或推荐的获取登录用户信息的方法。
示例:

using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace FunctionApp
{
    public static class Function1
    {
        [FunctionName("HttpTriggerCSharp")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            return req.CreateResponse(HttpStatusCode.OK, "Hello " + ClaimsPrincipal.Current.Identity.Name);
        }
    }
}
erhoui1w

erhoui1w4#

与App Service EasyAuth的一流集成尚未到位,但我们正在我们的repo here中进行跟踪。我们现在正在研究这个问题,可能很快就会在这方面有所改进。
正如您所发现的,您可以启用EasyAuth,它将需要登录,并将通过身份验证的主体,允许您通过标准.NET API(如ClaimsPrincipal.Current等)访问它。然而,问题是你必须用auth level Anonymous来标记你的方法,这不是你想要的,并且要求你在你的方法中拒绝未经身份验证的请求(参见上面引用的问题中的注解)。
我们将在即将发布的版本中解决所有这些问题。

68de4m5k

68de4m5k5#

从我这里的问题复制,该问题旨在了解如何使用Azure Active Directory身份验证用户进行本地调试。
https://stackoverflow.com/a/49402152/3602057
这将适用于在Azure上使用Azure Function配置的任何提供程序,并且适用于本地调试和部署方案。
好吧,又过了几个(好吧,很多)小时,我现在已经想出了一个解决方案。这在本地和已部署的场景中都有效。我在这里发布了一个模板解决方案:
https://github.com/Mike-EEE/Stash/tree/master/AzureV2Authentication/AzureV2Authentication
以下是概述整个过程的步骤:
1.登录您的函数https://function-name. azurewebsites.net

  1. Chrome中的CTRL-SHIFT-C->应用程序-> Cookie-> AppServiceAuthSession ->复制值
    1.打开local.settings.json并将上一步的值粘贴到AuthenticationToken设置中。
    1.当你在那里,粘贴在URL从第一步在AuthenticationBaseAddress
    1.启动应用程序。
    1.交叉手指。
    1.享受魔法(希望如此)。
    以下是主要事件:
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。这是违背最佳实践的。
1.示例代码基于EasyAuth sample by @stuartleeks
1.该解决方案利用了优秀的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. :(");
    }
}
ffx8fchx

ffx8fchx6#

对于任何在2023年及以后查看此内容的人,请更新您想要查看的https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-user-identities,其中显示了X-MS-CLIENT-PRINCIPAL头的使用。鉴于MS的工作方式,我不知道它是否适用于他们的每一种认证技术,但我使用它与静态Web应用程序和Azure函数集成。

相关问题