C# 如何从此web应用共享凭据的后端调用此API?它们位于不同的Azure环境中,但位于同一域中

C# 如何从此web应用共享凭据的后端调用此API?它们位于不同的Azure环境中,但位于同一域中,c#,.net,azure,httpwebrequest,ntlm,C#,.net,Azure,Httpwebrequest,Ntlm,我不太喜欢.NET,我发现了以下困难 我有一个与此类似的用例: 基本上,我有一个运行在Azure云中的.NET web应用程序(用户可以登录)(它是一个运行在SharePoint中的应用程序,我不知道它是否可能是相关的详细信息) 在这个webapp的后端,我实现了一个ApiController控制器,它必须调用另一个restapi 第二个API正在另一个环境(它应该是Azure上的一台机器)上运行,但这两个环境应该以某种方式“共享”凭据。我认为这是非常重要的一点,我试图在实践中解释这种情况:

我不太喜欢.NET,我发现了以下困难

我有一个与此类似的用例:

基本上,我有一个运行在Azure云中的.NET web应用程序(用户可以登录)(它是一个运行在SharePoint中的应用程序,我不知道它是否可能是相关的详细信息)

在这个webapp的后端,我实现了一个ApiController控制器,它必须调用另一个restapi

第二个API正在另一个环境(它应该是Azure上的一台机器)上运行,但这两个环境应该以某种方式“共享”凭据。我认为这是非常重要的一点,我试图在实践中解释这种情况:

  • 我的.NETweb应用程序运行在环境A上。用户可以通过插入其凭据登录到此应用程序

  • 在另一个环境中,B正在运行前一个web应用程序必须调用的API。端点类似于:*(正如您所看到的,它在azure VM上运行)

  • web应用程序和API在中的两个不同环境中运行,但它们共享凭据(我不知道详细信息,但它是这样工作的,我认为它们应该位于同一个域上)。这个断言的证据是,如果我调用我的API(从浏览器),它会询问我的用户凭证(在borwser弹出窗口中)。但是,如果我首先登录到我的web应用程序(在环境A上运行),然后在另一个浏览器选项卡上调用我的API(在环境B上运行),它将直接访问,因为它知道我已登录到系统

我要做的是允许web应用程序的后端(在环境A上运行)使用登录用户的凭据调用此API(在环境B上运行)

所以我试图实施前一个post策略

我以这种方式实现了我的控制器:

[SharePointContextWebAPIFilter]
[HttpGet]
[ActionName("GetAooList2")]
public IHttpActionResult GetAooList2()
{
    Console.WriteLine("INTO GetAooList2()");

    string jsonRequest = urlBaseProtocolloApi + "/api/ProtocollaMail/GetListAOO";

    var wi = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;
    var wic = wi.Impersonate();

    ..............................................................
    ..............................................................
    ..............................................................

    return Ok("TEST");

}
[SharePointContextWebAPIFilter]
[HttpGet]
[ActionName("GetAooList")]
public IHttpActionResult GetAooList()
{
    Console.WriteLine("INTO GetAooList()");

    string jsonRequest = urlBaseProtocolloApi + "/API_TO_BE_CALLED";

    NetworkCredential myCreds = new NetworkCredential("MY_USERNAME", "MY_PSWD", "THE_DOMAIN");

    CredentialCache credCache = new CredentialCache();

    credCache.Add(new Uri(jsonRequest), "NTLM", myCreds);

    //credCache.Add(new Uri(jsonRequest), "NTLM", CredentialCache.DefaultNetworkCredentials);

    HttpWebRequest spRequest = (HttpWebRequest)HttpWebRequest.Create(jsonRequest);
    spRequest.Credentials = credCache;
    spRequest.UserAgent = "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0";
    spRequest.Method = "GET";
    spRequest.Accept = "application/json;odata=verbose";

    HttpWebResponse endpointResponse = (HttpWebResponse)spRequest.GetResponse();

    ..........................................................................................
    ..........................................................................................
    ..........................................................................................
}
我的想法是在执行呼叫之前获取已登录的用户凭据并模拟这些凭据

问题是,当执行Impersonate()方法时,我会获得以下异常:

System.InvalidOperationException: 'An anonymous identity cannot perform an impersonation.'
System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'
所以我认为它无法恢复身份。查看wi对象(我调用impersonate()方法的对象),我发现属性设置为true,在我看来,它似乎不包含登录用户的信息

如前所述,我不喜欢.NET,可能我错过了什么,什么

使用此代码,我要模拟的用户是什么

我还尝试使用另一个实现:

public class MailProtocolloController : ApiController
{

    private String urlBaseProtocolloApi = "http://MY_MACHINE_NAME.westeurope.cloudapp.azure.com:8081/PI_WebAPI";

    [SharePointContextWebAPIFilter]
    [HttpGet]
    [ActionName("GetAooList")]
    public IHttpActionResult GetAooList()
    {
        string jsonRequest = urlBaseProtocolloApi + "/API_TO_BE_CALLED";

        CredentialCache credCache = new CredentialCache();

        credCache.Add(new Uri(jsonRequest), "NTLM", CredentialCache.DefaultNetworkCredentials);

        HttpWebRequest spRequest = (HttpWebRequest)HttpWebRequest.Create(jsonRequest);
        spRequest.Credentials = credCache;
        spRequest.UserAgent = "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0";
        spRequest.Method = "GET";
        spRequest.Accept = "application/json;odata=verbose";

        HttpWebResponse endpointResponse = (HttpWebResponse)spRequest.GetResponse();

        ...............................................................................
        ...............................................................................
        ...............................................................................
    }
}
如您所见,我正在尝试检索我的web应用程序的DefaultNetworkCredentials(我希望它是记录的用户凭据,我应该使用它来执行对第二个REST API的调用)。但它不起作用,事实上,在执行这一行时,它是这样做的:

HttpWebResponse endpointResponse = (HttpWebResponse)spRequest.GetResponse();
我获得以下例外情况:

System.InvalidOperationException: 'An anonymous identity cannot perform an impersonation.'
System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'
但我认为这可能是一种接近“好方法”(使用NTLM协议)的方法,因为如果改用DefaultNetworkCredentials我在代码中手动设置了我的凭据,它工作得很好,并且我正确地获得了REST API响应

我是这样做的:

[SharePointContextWebAPIFilter]
[HttpGet]
[ActionName("GetAooList2")]
public IHttpActionResult GetAooList2()
{
    Console.WriteLine("INTO GetAooList2()");

    string jsonRequest = urlBaseProtocolloApi + "/api/ProtocollaMail/GetListAOO";

    var wi = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;
    var wic = wi.Impersonate();

    ..............................................................
    ..............................................................
    ..............................................................

    return Ok("TEST");

}
[SharePointContextWebAPIFilter]
[HttpGet]
[ActionName("GetAooList")]
public IHttpActionResult GetAooList()
{
    Console.WriteLine("INTO GetAooList()");

    string jsonRequest = urlBaseProtocolloApi + "/API_TO_BE_CALLED";

    NetworkCredential myCreds = new NetworkCredential("MY_USERNAME", "MY_PSWD", "THE_DOMAIN");

    CredentialCache credCache = new CredentialCache();

    credCache.Add(new Uri(jsonRequest), "NTLM", myCreds);

    //credCache.Add(new Uri(jsonRequest), "NTLM", CredentialCache.DefaultNetworkCredentials);

    HttpWebRequest spRequest = (HttpWebRequest)HttpWebRequest.Create(jsonRequest);
    spRequest.Credentials = credCache;
    spRequest.UserAgent = "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0";
    spRequest.Method = "GET";
    spRequest.Accept = "application/json;odata=verbose";

    HttpWebResponse endpointResponse = (HttpWebResponse)spRequest.GetResponse();

    ..........................................................................................
    ..........................................................................................
    ..........................................................................................
}
如您所见,使用这一行:

NetworkCredential myCreds = new NetworkCredential("MY_USERNAME", "MY_PSWD", "THE_DOMAIN");
在我设置的用户名密码(web应用程序和API应该在不同的环境中运行,但在同一个域)中,它工作正常,API调用正确

显然,我不能将这些信息模拟到我的控制器方法代码中。我需要一种方法来检索这些凭证信息并使用它

有什么想法吗?我怎么做?我缺少什么?

我想您可能需要使用“连接字符串”