0

For example, I have a web page (ASP.NET MVC), where I get cookie for some resource.

My MVC controller action code:

        CookieContainer cookies = new CookieContainer();
        HttpClientHandler handler = new HttpClientHandler();
        handler.CookieContainer = cookies;
        string data = "<Request><MsgType>Authenticate</MsgType><SubMsgType>Login</SubMsgType><UserID>MYLOGIN</UserID><passwordNotEncrypted>MYPASSWORD</passwordNotEncrypted></Request>";
        StringContent content = new StringContent(data, Encoding.UTF8, "text/xml");

        HttpClient client = new HttpClient(handler);
        Uri uri = new Uri("https://address/browserservices.aspx/login");
        HttpResponseMessage response = client.PostAsync(uri, content).Result;

this request set auth cookie to cookies variable. And next request works fine:

        var result = client.GetAsync("https://address/RemoteSupport.aspx?id=bla-bla-bla&pltFrmType=Android&agentversion=13.46").Result;
        var text = result.Content.ReadAsStringAsync().Result;

(if I call it without cookie I get Unauthorized response)

Right now I want to do a redirect to this https://address/RemoteSupport.aspx?id=bla-bla-bla&pltFrmType=Android&agentversion=13.46 address with cookie. So, user should look at it redirected to this address. How to do it?

I tried:

        foreach (Cookie cookie in responseCookies)
        {
            Response.Cookies.Append(cookie.Name, cookie.Value);
        }

        return Redirect($"https://address/RemoteSupport.aspx?id={id}&pltFrmType=Android&agentversion=13.46");

but it does not work

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159

1 Answers1

0

You can't just do a Redirect. In MVC that returns a 302 status code to the browser that instructs it to make it's own request to the 3rd party site.

Using the same instance of the HttpClient you need to make a second request to the 3rd party server. This should automatically add the cookie to the new request, and you can then format the answer and pass it on to your browser client.

Ideally you should not instantiate the HttpClient in the method, as this means that you have to make 2 requests each time. Perhaps something like this:

public class MyController : Controller
{
    private static readonly HttpClient _httpClient;

    public MyController()
    {
        if (_httpClient == null)
        {
            CookieContainer cookies = new CookieContainer();
            HttpClientHandler handler = new HttpClientHandler();
            handler.CookieContainer = cookies;
            _httpClient = new HttpClient(handler);

            LoginWithClient();
        }
    }

    private void LoginWithClient()
    {
        string data = "<Request><MsgType>Authenticate</MsgType><SubMsgType>Login</SubMsgType><UserID>MYLOGIN</UserID><passwordNotEncrypted>MYPASSWORD</passwordNotEncrypted></Request>";
        StringContent content = new StringContent(data, Encoding.UTF8, "text/xml");  
        Uri uri = new Uri("https://address/browserservices.aspx/login");
        HttpResponseMessage response = client.PostAsync(uri, content).Result; 
        // Maybe check the result here, but we should have the cookie by now
    }

    public JsonResult MyAction()
    {
        var result = client.GetAsync("https://address/RemoteSupport.aspx?id=bla-bla-bla&pltFrmType=Android&agentversion=13.46").Result;
        var text = result.Content.ReadAsStringAsync().Result;
        return Json(text, JsonRequestBehavior.AllowGet);
    }

This should return the raw text string to the browser where you can display it, or parse it as Json or XML or whatever and work with the data.

ste-fu
  • 6,879
  • 3
  • 27
  • 46
  • no-no, I don't need to get data. I need to make a redirect, so user should work with "address" (all links inside that page should work etc) – Oleg Sh Jan 29 '19 at 14:35
  • Oleg - as per your previous question I think you are out of luck. Whilst you could pass the cookie in your response to the ajax method, the headers set by the external site will prevent an ajax request working. You can't set the cookie for an alternative site either – ste-fu Jan 30 '19 at 12:17
  • when we enter credentials on website - it set cookie. In my case I don't need enter credentials (already predefined), but just send POST request. Why I'm out of luck? – Oleg Sh Jan 31 '19 at 20:36
  • Because I think the server will refuse the ajax request because of its allowed origin headers. Also you can't redirect an entire page via a ajax request, you can set `window.location` in JavaScript, but you can't instruct the browser to attach your own cookie. You **could** maybe proxy the response in an iFrame? – ste-fu Feb 01 '19 at 10:11
  • Could you show me how to do it via frames? Seems, I really weak in this sphere :) https://stackoverflow.com/questions/54489890/how-to-implement-it-via-iframe – Oleg Sh Feb 02 '19 at 04:09