加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 重定向时丢失授权标头

发布时间:2020-12-16 01:21:04 所属栏目:百科 来源:网络整理
导读:下面是进行身份验证的代码,生成Authorization标头并调用API. 不幸的是,我在API上发出GET请求后收到401 Unauthorized错误. 但是,当我捕获Fiddler中的流量并重放它时,对API的调用成功,我可以看到所需的200 OK状态代码. [Test]public void RedirectTest(){ Http
下面是进行身份验证的代码,生成Authorization标头并调用API.

不幸的是,我在API上发出GET请求后收到401 Unauthorized错误.

但是,当我捕获Fiddler中的流量并重放它时,对API的调用成功,我可以看到所需的200 OK状态代码.

[Test]
public void RedirectTest()
{
    HttpResponseMessage response;
    var client = new HttpClient();
    using (var authString = new StringContent(@"{username: ""theUser"",password: ""password""}",Encoding.UTF8,"application/json"))
    {
        response = client.PostAsync("http://host/api/authenticate",authString).Result;
    }

    string result = response.Content.ReadAsStringAsync().Result;
    var authorization = JsonConvert.DeserializeObject<CustomAutorization>(result);
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authorization.Scheme,authorization.Token);
    client.DefaultRequestHeaders.Add("Accept","application/vnd.host+json;version=1");

    response =
        client.GetAsync("http://host/api/getSomething").Result;
    Assert.True(response.StatusCode == HttpStatusCode.OK);
}

当我运行此代码时,Authorization标头丢失.

但是,在Fiddler中,标题成功传递.

知道我做错了什么吗?

解决方法

您遇到此行为的原因是它是设计的.

遵循重定向时,大多数HTTP客户端(默认情况下)会删除授权标头.

一个原因是安全.客户端可能会被重定向到不受信任的第三方服务器,您不希望向其披露您的授权令牌.

您可以做的是检测重定向是否已发生,并将请求直接重新发送到正确的位置.

您的API返回401 Unauthorized以指示授权标头丢失(或不完整).我将假设如果请求中存在授权信息,则相同的API将返回403 Forbidden但是不正确(用户名/密码错误).

如果是这种情况,您可以检测“重定向/丢失授权标头”组合并重新发送请求.

以下是重写的问题的代码:

[Test]
public void RedirectTest()
{
    // These lines are not relevant to the problem,but are included for completeness.
    HttpResponseMessage response;
    var client = new HttpClient();
    using (var authString = new StringContent(@"{username: ""theUser"",authString).Result;
    }

    string result = response.Content.ReadAsStringAsync().Result;
    var authorization = JsonConvert.DeserializeObject<CustomAutorization>(result);

    // Relevant from this point on.
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authorization.Scheme,"application/vnd.host+json;version=1");

    var requestUri = new Uri("http://host/api/getSomething");
    response = client.GetAsync(requestUri).Result;

    if (response.StatusCode == HttpStatusCode.Unauthorized)
    {
        // Authorization header has been set,but the server reports that it is missing.
        // It was probably stripped out due to a redirect.

        var finalRequestUri = response.RequestMessage.RequestUri; // contains the final location after following the redirect.

        if (finalRequestUri != requestUri) // detect that a redirect actually did occur.
        {
            if (IsHostTrusted(finalRequestUri)) // check that we can trust the host we were redirected to.
            {
               response = client.GetAsync(finalRequestUri).Result; // Reissue the request. The DefaultRequestHeaders configured on the client will be used,so we don't have to set them again.
            }
        }
    }

    Assert.True(response.StatusCode == HttpStatusCode.OK);
}


private bool IsHostTrusted(Uri uri)
{
    // Do whatever checks you need to do here
    // to make sure that the host
    // is trusted and you are happy to send it
    // your authorization token.

    if (uri.Host == "host")
    {
        return true;
    }

    return false;
}

请注意,您可以保存finalRequestUri的值并将其用于将来的请求,以避免重试中涉及的额外请求.但是,由于这是临时重定向,因此您应该每次都将请求发送到原始位置.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读