C# 如何从此web应用共享凭据的后端调用此API?它们位于不同的Azure环境中,但位于同一域中
我不太喜欢.NET,我发现了以下困难 我有一个与此类似的用例: 基本上,我有一个运行在Azure云中的.NET web应用程序(用户可以登录)(它是一个运行在SharePoint中的应用程序,我不知道它是否可能是相关的详细信息) 在这个webapp的后端,我实现了一个ApiController控制器,它必须调用另一个restapi 第二个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上的一台机器)上运行,但这两个环境应该以某种方式“共享”凭据。我认为这是非常重要的一点,我试图在实践中解释这种情况:
- 我的.NETweb应用程序运行在环境A上。用户可以通过插入其凭据登录到此应用程序
- 在另一个环境中,B正在运行前一个web应用程序必须调用的API。端点类似于:*(正如您所看到的,它在azure VM上运行)
- web应用程序和API在中的两个不同环境中运行,但它们共享凭据(我不知道详细信息,但它是这样工作的,我认为它们应该位于同一个域上)。这个断言的证据是,如果我调用我的API(从浏览器),它会询问我的用户凭证(在borwser弹出窗口中)。但是,如果我首先登录到我的web应用程序(在环境A上运行),然后在另一个浏览器选项卡上调用我的API(在环境B上运行),它将直接访问,因为它知道我已登录到系统
[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调用正确
显然,我不能将这些信息模拟到我的控制器方法代码中。我需要一种方法来检索这些凭证信息并使用它
有什么想法吗?我怎么做?我缺少什么?我想您可能需要使用“连接字符串”