Как вызвать этот API из серверной части этого веб-приложения для обмена данными?Они находятся в другой среде Azure, но в одном домене. - PullRequest
0 голосов
/ 16 ноября 2018

Мне не очень нравится .NET, и я нахожу следующие сложности.

У меня есть пример использования, подобный этому: Как заставить HttpClient передавать учетные данные вместе с запросом?

По сути, у меня есть веб-приложение .NET (в которое пользователи могут войти), работающее в облаке Azure (это приложение, работающее в SharePoint, я не знаю, может ли это быть уместно).

В серверной части этого веб-приложения я реализовал контроллер ApiController , который должен вызывать еще один второй REST API.

Этот второй API-интерфейс работает в другой среде (это должен быть компьютер в Azure), но обе эти среды должны каким-то образом «совместно использовать» учетные данные. Я думаю, что это очень важный момент, я пытаюсь объяснить ситуацию на практике:

  • У меня есть веб-приложение .NET , работающее в среде A . Пользователь может войти в это приложение, вставив свои учетные данные.

  • В другой среде B использует API , который должно вызывать предыдущее веб-приложение. Конечная точка выглядит примерно так: *http://MY_MACHINE_NAME.westeurope.cloudapp.azure.com:8081/PI_WebAPI/API_TO_BE_CALLED (как вы можете видеть, она работает на лазурной виртуальной машине).

  • Веб-приложение и API работают в двух разных средах, но имеют общие учетные данные (я не знаю деталей, но это работает таким образом, я думаю, что они должны быть на тот же домен ). Доказательством этого утверждения является то, что если я вызываю мой API (из браузера), он спрашивает мои учетные данные пользователя (в всплывающем окне borwser). Но если я сначала войду в свое веб-приложение (работающее в среде A), а затем вызову свой API (работающий в среде B) на другой вкладке браузера, он получит прямой доступ, потому что знает, что я вошел в систему.

Что мне нужно сделать, так это разрешить бэкэнду моего веб-приложения (работающего в среде 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");

}

Моя идея состоит в том, чтобы получить учетные данные зарегистрированного пользователя и олицетворять эти учетные данные перед выполнением моего вызова.

Проблема в том, что при выполнении метода Impersonate () я получаю следующее исключение:

System.InvalidOperationException: 'An anonymous identity cannot perform an impersonation.'

Так что я думаю, что он не может восстановить личность. Заглядывая в объект wi (тот, для которого я вызываю метод impersonate ()), я обнаружил свойство IsAnonymous , установленное в 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();

        ...............................................................................
        ...............................................................................
        ...............................................................................
    }
}

Как вы видите, я пытаюсь получить DefaultNetworkCredentials моего веб-приложения (которое я ожидал получить в качестве учетных данных зарегистрированного пользователя, которые я должен использовать для выполнения вызова моего второго REST API). Но это не работает, например, когда вы выполняете эту строку, выполните следующие действия:

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

Я получаю следующее исключение:

System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'

Но я думаю, что это может быть что-то вроде "хорошего пути" (с использованием протокола NTLM ), потому что если вместо этого использовать DefaultNetworkCredentials , я вручную устанавливаю свои учетные данные в код работает нормально, и я правильно получаю ответ REST API.

Я сделал это следующим образом:

[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");

, в котором я устанавливаю имя пользователя , пароль и DOMAIN (веб-приложение и API должны работать в разных средах, но на тот же домен ) он работает нормально и API правильно называется.

Очевидно, я не могу смоделировать эту информацию в коде моего контроллера. Мне нужен способ получить эти учетные данные и использовать их.

Есть идеи? Как мне это сделать? Чего мне не хватает?

...