Вызвать API другого приложения, у которого есть аутентификация формы

#c# #asp.net-mvc

#c# #asp.net-mvc

Вопрос:

У меня есть приложение MVC, размещенное в локальном IIS, которое имеет аутентификацию формы. <system.web> настройка:

   <system.web>
    <compilation debug="true" targetFramework="4.8"/>
    <httpRuntime targetFramework="4.8"/>
    <authentication mode="Forms">
      <forms loginUrl="~/Login" timeout="2880"/>
    </authentication>
    <authorization>
      <allow users="?" verbs="OPTIONS"/>
      <deny users="?"/>
    </authorization>
  </system.web>
  

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

У него есть API, который является методом POST и возвращает список.

введите описание изображения здесь

Я получаю доступ к этому API с помощью ajax в пользовательском интерфейсе. ajax вызывает javascript

В этом приложении он работает нормально. Теперь у меня есть другое приложение MVC, которое находится в облаке Azure, и ему необходимо получить доступ к этому API. Когда я вызываю его (http://my-premise-application.com/api/customer/list ), он возвращает содержимое страницы входа в систему. Какой возможный способ вызвать api первого приложения из второго приложения? Любые предложения или рекомендации были бы полезны.

Комментарии:

1. Вы хотите получить доступ к своему API из другого проекта MVC с помощью javascript, которым вы поделились. Я правильно вас понял?

2. @G.Dimov, я хочу попасть через код C #

3. Можете ли вы изменить аутентификацию в системе on Prem? Если нет, вам нужно, чтобы приложение c # выполняло процесс входа в систему.

Ответ №1:

Как вы упомянули в комментариях, вам необходимо выполнить HTTP-вызов C # для другого веб-API проекта. Вы можете сделать это, создав в любом месте вашего проекта класс с именем MakeRequestService и один static метод с именем MakeWebRequest , который вернет строку, являющуюся нужным вам JSON.

 public class MakeRequestService
{
    public static string MakeWebRequest(string url, string verb, int timeout, Dictionary<string, string> headers = null, string contentType = "", string json = "")
    {
        string myResult = string.Empty;
    
        try
        {
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
            myRequest.Method = verb;
            myRequest.Timeout = timeout;
    
            if (!string.IsNullOrEmpty(contentType))
                myRequest.ContentType = contentType;
    
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    if (header.Key == HttpRequestHeader.Accept.ToString())
                        myRequest.Accept = header.Value;
                    else
                        myRequest.Headers.Add(header.Key, header.Value);
                }
            }
    
            if (!string.IsNullOrEmpty(json))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(json);
                myRequest.ContentLength = bytes.Length;
    
                using (var streamWriter = new StreamWriter(myRequest.GetRequestStream()))
                {
                    streamWriter.Write(json);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
            }
    
            using (HttpWebResponse response = myRequest.GetResponse() as HttpWebResponse)
            {
                StreamReader reader = new StreamReader(response.GetResponseStream());
                myResult = reader.ReadToEnd();
            }
        }
        catch (WebException ex)
        {
            if (ex.Status == WebExceptionStatus.ProtocolError)
            {
                if (ex.Response is HttpWebResponse response)
                {                
                    Stream stream = response.GetResponseStream();
                    StreamReader sr = new StreamReader(stream: stream);
                    myResult = sr.ReadToEnd();
                    stream.Position = 0;                
                }
            }
            else
            {
                myResult = ex.Message;
            }
        }
    
        return myResu<
    }
}
  

Затем вы можете использовать этот метод следующим образом:

 string res = MakeRequestService.MakeWebRequest(
    url: "The FULL URL of the first project, based on your example, e.g. http://localhost:69963/api/customer",
    verb: "POST",
    contentType: "application/json"
    );

var outcome = JsonConvert.DeserializeObject<IEnumerable<Customer>>(res);
  

catch Блок в MakeWebRequest методе является просто примером и вернет простую строку, содержащую тело ошибки JSON, в случае неудачного вызова API. Вы можете изменить его для своих нужд, например, перестроить WebException и обработать его так, как вы хотите.

MakeWebRequest Метод очень абстрактный, поэтому вы можете использовать его и для вызовов API. Если вы делаете POST запрос с телом JSON — просто передайте тело json параметру. Если вы делаете GET запрос с параметрами запроса, просто создайте весь URL-адрес, содержащий параметры запроса, а затем вызовите метод.

Комментарии:

1. Где находится часть входа в систему?

2. как видно из вопроса, метод не требует авторизации

3. «Итак, когда пользователь не аутентифицирован, он перенаправляется на страницу входа» web.config требует аутентифицированных пользователей.

4. «Теперь у меня есть другое приложение MVC, которое находится в облаке Azure, и ему необходимо получить доступ к этому API».

5. Я полагаю, что API является частью приложения Forms auth MVC.

Ответ №2:

Вот некоторый код, который я использую для входа в систему с помощью приложения на C #. Вам нужно будет внести изменения для работы с вашим приложением. SharedCookie необходимо будет добавлять к каждому будущему запросу, поскольку в него включен файл cookie вашего сеанса.

     public void Login()
    {
        byte[] bytes;
        string data;
        SharedCookie = new CookieContainer();

        var url = Host   "/login";
        
        try
        {
            //Start Session
            var request = CreateRequest(url, "GET");
            request.CookieContainer = SharedCookie;

            using (var tmpResponse = request.GetResponse())
            {
                DoWriteResponse(tmpResponse);
                tmpResponse.Close();
            }

            //Login
            
            data = "username=useramp;password=pass";
            bytes = Encoding.UTF8.GetBytes(data);

            request = CreateRequest(url, "POST");
            request.CookieContainer = SharedCookie;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(bytes, 0, bytes.Length);
            }

            using (var tmpResponse = request.GetResponse())
            {
                DoWriteResponse(tmpResponse);
                tmpResponse.Close();
            }
            IsLoggedIn = true;
        }
        catch (System.Net.WebException ex)
        {
            Console.WriteLine("Web Error:"   ex.Status);
            Console.WriteLine("Url:"   url);
            Console.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Url:"   url);
            Console.WriteLine(ex.Message);
        }
    }

    private void DoWriteResponse(WebResponse tmpResponse)
    {
        if (debug)
        {
            Console.WriteLine("************BEGIN**************");
            Console.WriteLine("************"   tmpResponse.ResponseUri   "**************");
            Console.WriteLine("*******************************");
            using (var reader = new StreamReader(tmpResponse.GetResponseStream()))
            {
                var pageText = reader.ReadToEnd();
                Console.WriteLine(pageText);
            }
            Console.WriteLine("*************END***************");
        }
    }

    private HttpWebRequest CreateRequest(string url, string method)
    {
        var request = (HttpWebRequest)WebRequest.Create(url);
        request.Referer = Host;
        request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36";
        request.Method = method;
        request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";

        return request;
    }