首页 > 解决方案 > HttpClient 在重定向时传递 Location 等于 null(而相应的浏览器调用包含 URL)

问题描述

我得到一个 cookie 并使用它,继续模拟相应浏览器步骤给出的步骤。由于自动重定向已关闭,我必须单独执行每个步骤,然后在下一步中使用它来获取响应标头中的位置。经过三个这样的操作,响应的标头包含位置字段,但它是空的。使用浏览器执行相应的操作,在每个重定向步骤中都包含一个实际位置。

private static Uri ObtainExecutor(Uri referer, Uri uri, Cookie cookie)
{
  CookieContainer cookieJar = new CookieContainer();
  cookieJar.Add(cookie);
  HttpClientHandler handler = new HttpClientHandler
  {
    CookieContainer = cookieJar,
    AllowAutoRedirect = false
  };
  HttpClient client = new HttpClient(handler);
  client.DefaultRequestHeaders.Referrer = referer;
  client.DefaultRequestHeaders.Host = uri.Host;

  HttpResponseMessage response = client.GetAsync(uri).Result;
  HttpResponseHeaders headers = response.Headers;
  return new Uri(uri, response.Headers.Location);
}

我不知道如何进一步解决它。我比较了标题,没有注意到任何相关性。我用同样的结果搜索它,无法掌握进来的包裹超载。当然,我也用谷歌搜索了一个多星期。

我确信调用的执行方式存在微小差异,但我无法看到它。下面的示例连接到实际服务器,并显示了缺少重定向位置的位置。(对于大样本,我深表歉意——我试图将其最小化,但确保不要遗漏我不清楚的相关细节。)

class Program
{
  static void Main(string[] args)
  {
    const string url = "https://www.pensionsmyndigheten.se/service/login/login"
    + "?targetPage=https://www.pensionsmyndigheten.se/service/overview/"
    + "&failurePage=https://www.pensionsmyndigheten.se/service/login/error/login-failed"
    + "&cancelPage=https://www.pensionsmyndigheten.se/";
    Uri uri = new Uri(url);

    Cookie cookie = GenerateCookie(uri);
    Uri discovery = DiscoverService(cookie);
    Uri execution = ObtainExecutor(uri, discovery, cookie);
    Uri conversation = ObtainConversor(uri, execution, cookie);
  }

  private static Cookie GenerateCookie(Uri uri)
  {
    CookieContainer cookieJar = new CookieContainer();
    HttpClientHandler handler = new HttpClientHandler { CookieContainer = cookieJar };
    HttpClient client = new HttpClient(handler);

    HttpResponseMessage response = client.GetAsync(uri).Result;
    HttpContent content = response.Content;

    Cookie cookie = cookieJar.GetCookies(uri)
      .Cast<Cookie>()
      .First(e => e.Name == "pm_retention_urls");

    return cookie;
  }

  private static Uri DiscoverService(Cookie cookie)
  {
    string url = "https://www.pensionsmyndigheten.se/service/login/discoresponse"
      + "?spId=default"
      + "&entityID=https%3A%2F%2Feid.legitimeringstjanst.se%2Fmobilt-bankid%2F";
    Uri uri = new Uri(url);
    CookieContainer cookieJar = new CookieContainer();
    cookieJar.Add(cookie);
    HttpClientHandler handler = new HttpClientHandler
    {
      CookieContainer = cookieJar,
      AllowAutoRedirect = false
    };
    HttpClient client = new HttpClient(handler);
    client.DefaultRequestHeaders.Referrer = uri;
    client.DefaultRequestHeaders.Host = uri.Host;

    HttpResponseMessage response = client.GetAsync(uri).Result;
    HttpResponseHeaders headers = response.Headers;

    return headers.Location;
  }

  private static Uri ObtainExecutor(Uri referer, Uri uri, Cookie cookie)
  {
    CookieContainer cookieJar = new CookieContainer();
    cookieJar.Add(cookie);
    HttpClientHandler handler = new HttpClientHandler
    {
      CookieContainer = cookieJar,
      AllowAutoRedirect = false
    };
    HttpClient client = new HttpClient(handler);
    client.DefaultRequestHeaders.Referrer = referer;
    client.DefaultRequestHeaders.Host = uri.Host;

    HttpResponseMessage response = client.GetAsync(uri).Result;
    HttpResponseHeaders headers = response.Headers;
    return new Uri(uri, response.Headers.Location);
  }

  private static Uri ObtainConversor(Uri referer, Uri uri, Cookie cookie)
  {
    CookieContainer cookieJar = new CookieContainer();
    cookieJar.Add(cookie);
    HttpClientHandler handler = new HttpClientHandler
    {
      CookieContainer = cookieJar,
      AllowAutoRedirect = false
    };
    HttpClient client = new HttpClient(handler);
    client.DefaultRequestHeaders.Referrer = referer;
    client.DefaultRequestHeaders.Host = uri.Host;

    HttpResponseMessage response = client.GetAsync(uri).Result;
    HttpResponseHeaders headers = response.Headers;

    // Figure out why the returned redirection URL is empty.
    Uri redirection = headers.Location;
    // It should be containing the following value.
    redirection = new Uri(
      "https://idpproxy.pensionsmyndigheten.se/idp/Authn/SamlSP?conversation=e1s1");

    return redirection;
  }
}

标签: c#redirect.net-coredotnet-httpclient.net-core-2.2

解决方案


推荐阅读