将凭据从Web应用程序传递到Web API。Azure AD身份验证

4
我有一个常规的ASP .NET Web应用程序,我使用App Services将其部署到Azure。部署后,我启用了App Service身份验证并配置了Azure Active Directory。这使我能够发布我的Web应用程序,并进行身份验证,因此只有Active Directory中的人才能登录。

enter image description here

另一方面,我部署了一个ASP .NET Web API作为云服务。Web应用程序应该调用Web API(从SQL数据库加载一些数据并返回)以加载一些信息,然后在UI中显示信息。但是,当我调用API时,Azure Active Directory凭据未从Web应用程序传递到Web API。

以下是Web应用程序中调用Web API端点的一些代码。

public string GetStringAsync(string endPoint)
{
    HttpClientHandler handler = new HttpClientHandler
    {
        UseDefaultCredentials = true
    };
    handler.PreAuthenticate = true;
    using (HttpClient client = new HttpClient(handler))
    {
        return client.GetStringAsync(endPoint).Result;
    }
}

但是当我尝试在调用API时获取用户名时,得到的是一个空字符串。以下是我捕获调用API者身份的方法:

HttpContext.Current.User.Identity.Name;

当Web应用程序调用Web API时,我如何获取Azure Active Directory域\用户信息?可能我的调用API的函数完全错误吗?

您的Web应用程序应从Azure AD获取API的访问令牌,并将其作为请求标头附加到HTTP调用中。 - juunas
3个回答

2
根据描述,您在Azure上部署Web应用程序并使用Azure AD保护Web应用程序。
据我所知,在这种情况下,不可能将凭据传递给Web API。相应的解决方案是,您应该使用Azure AD保护Web API(我们可以使用保护Web应用程序的同一应用程序),并获取Web API的access_token。然后,Web应用程序可以使用access_token调用Web API。
要配置易于身份验证以获取Web API的令牌,您可以参考此博客(第2步:通过REST API更新应用服务身份验证配置)并将资源值替换为保护Web API的应用程序的APP ID。要从Web应用程序获取access_token,您可以遵循该博客的调用图形API作为最终用户部分。

那么你的意思是我无法知道调用API的域/用户是谁?API需要这些信息以后才能根据域/用户提供定制内容。 - user3587624
您无法通过凭据进行验证。但是,如果Web API受AAD保护,则可以了解用户。您可以解码令牌以获取当前用户信息。有关此场景的更多详细信息,请参阅此文档中的Web应用程序调用Web API部分。 - Fei Xue - MSFT
如何获取用户在调用Web API的Web应用程序上登录时创建的令牌?this.Request.Headers ["X-MS-TOKEN-AAD-ACCESS-TOKEN"];返回的内容看起来不像Bearer令牌。此外,即使我使用应用程序ID和密钥在运行时生成一个令牌,在调用Web API时,我无法检索用户名、域/名称或任何其他类似的信息。我发现的唯一方法是将电子邮件地址作为HTTP请求的一部分从Web应用程序传递到Web API,但我认为这根本不正确。 - user3587624
1
一个更简单的方法是在 Web 应用程序和 Web API 中都使用 OWIN 组件。在这种情况下,无需为 Web 应用程序启用 Easy Auth。您可以参考此方案的代码示例此处 - Fei Xue - MSFT

0

1- 从 Web 应用程序中读取 .ASPX 授权 cookie

HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
string authToken = authCookie.Value;

2- 将cookie设置到httpclient中。cookie值必须与.ASPX auth cookie相同。

如何在HttpClient的HttpRequestMessage上设置cookie

3- 使用HttpContext.Current.User.Identity.Name从Web API读取用户名。

希望这可以帮助您。


你能提供一些文件或代码示例来说明你所描述的前两个步骤吗? - user3587624
实际上我无法使用Request.Cookies。显然,类型名称Cookies不存在。 - user3587624
您必须在 MVC 操作中读取 Cookie,而不是 WCF。或者您的意思是 WCF 服务不依赖于请求 Cookie 进行身份验证?我提到了 Cookie 是为了使 Windows 身份验证工作。我相信我没有很好地理解您的问题。 - Houssam Hamdan

0
[Authorize]
public IEnumerable<Object> Get()
{
 var owner = ObtainCurrentOwner();
 var assets = GetAssets(owner.Id);
 return result;
}

protected Owner ObtainCurrentOwner()
{
 return RavenSession.Query<Owner>().SingleOrDefault(x => 
           x.UserName == HttpContext.Current.User.Identity.Name);
}

public IEnumerable<Asset> GetAssets(int ownerID)
{
 return RavenSession.Query<Asset>().Where(x => x.OwnerId == ownerID);
}

这个方法被 [Authorize] 属性修饰。这个机制在 WCF 中已经被广泛使用。ASP.NET 会检查此请求中的 cookie,如果没有 cookie 存在,则请求将被拒绝。获取当前用户及其所有资产只需要使用 RavenSession 进行两个 LINQ 查询即可,但在此之前必须先打开 RavenSession。

https://www.codeproject.com/Articles/568115/Sample-application-RavenDB-KnockoutJS-Bootstrap-We


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接