【问题标题】:ASP.NET HTTP Authorization HeaderASP.NET HTTP 授权标头
【发布时间】:2011-06-08 04:35:54
【问题描述】:

我想知道为什么我的 asp.net 应用程序在我的帖子命名为“授权”时不会将标题添加到我的帖子中,但当我更改一个字符时会正常工作,比如“授权”。在其他网站的文档中,他们总是使用名称“授权”,所以我也想这样做,此时我只想了解原因。

我已经阅读了一些关于此的主题,但没有找到任何合乎逻辑的原因。

下面是我的代码:

string fileName = "c:\\xyz.xml";
string uri = "http://myserver/Default.aspx";
req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "text/xml";
byte[] authBytes = Encoding.UTF8.GetBytes("DDSServices:jCole2011".ToCharArray());
req.Headers.Add("Authorization", "BASIC " + Convert.ToBase64String(authBytes) );
req.Headers.Add("test", "test");
UTF8Encoding encoder = new UTF8Encoding();
byte[] data = encoder.GetBytes(this.GetTextFromXMLFile(fileName));
req.ContentLength = data.Length;
Stream reqStream = req.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
req.Headers.Add("Authorization", "BASIC" + Convert.ToBase64String(authBytes));
System.Net.WebResponse response = req.GetResponse();
System.IO.StreamReader reader = new StreamReader(response.GetResponseStream());
string str = reader.ReadToEnd();

另一个烦人的是当我通过提琴手添加监视变量时它工作正常。

【问题讨论】:

    标签: c# asp.net httpwebrequest


    【解决方案1】:

    对于 HTTP 基本授权,您应该使用 Credentials 属性。

    req.Credentials = new NetworkCredential("DDSServices", "jCole2011");

    这应该做你想做的事。而不是设置 Authorization 标头。

    【讨论】:

    • 或者有什么合乎逻辑的原因吗?与我们合作的一家非常大的第三方公司以同样的方式拥有他们授权的文档,所以我想知道原因。
    • Will 建议使用 NetworkCredential 方法要好得多。但是,您的方法也应该可以正常工作,尽管我不明白您为什么要这样做两次(一次在调用 GetRquestStream 之前,一次在之后。您应该在调用 GetRequestStream 之前执行一次。如果它仍然不起作用,请获取跟踪日志。说明在ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html
    • 你能告诉我为什么它更好吗?或者我在哪里可以读到为什么它更好?对我来说,似乎 NetworkCredentials 将与广告或表单身份验证相关联,我宁愿通过匿名连接,然后验证。不管怎样,有人能告诉我为什么吗?我现在几乎不在乎什么。
    • NetworkCredential 仅在收到 401 后发送 Authentication 标头。这可能不是你想要的......使用旧时尚方式:var credentialBuffer = new UTF8Encoding().GetBytes(aUserName + ":" + aPassword); request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
    • @WillHughes 这不是真的。我尝试使用 PreAuthenticate=true 但它不起作用。您发布的链接验证您需要第一次捕获 401。 "属性值类型:System.Boolean true 表示在身份验证发生后发送带有请求的 HTTP Authorization 标头;否则为 false。默认值为 false。"
    【解决方案2】:

    NetworkCredential 是一个很好的解决方案,但您调用的站点必须处理未经授权的 401 和响应中的 WWW-Authenticate 标头。

    客户:

    request.Credentials = new CredentialCache {{aUri, "Basic", new NetworkCredential(aUserName, aPassword)}};
    

    服务器:

    Response.ClearContent();
    Response.StatusCode = 401;
    Response.AddHeader("WWW-Authenticate", "Basic");
    Response.End();
    

    这将导致对服务器的 2 次命中。初始调用将在没有凭据的情况下转到服务器。当服务器以 401 和 WWW-Authenticate 标头(以及所需的身份验证类型)响应时,将使用请求中的凭据重新发送请求。

    【讨论】:

    • 这是真的,但是发回 401 Unauthorized,并且 WWW-Authenticate 标头是 HTTP Spec 的一部分。如果您想在第一个请求时强制发送标头,您可以通过 PreAuthenticate 方法执行此操作。此外 - IIS 自动处理发送回此响应,其他编写良好的 HTTP 服务器(如 Apache)也是如此。这是浏览器知道显示密码提示对话框的方式。
    【解决方案3】:

    我遇到了如何将身份验证/凭据添加到标头的问题。我通过以下方式找到了解决方案。

    string _auth = string.Format("{0}:{1}", "myUser","myPwd");
    string _enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(_auth));
    string _cred = string.Format("{0} {1}", "Basic", _enc);
    req.Headers[HttpRequestHeader.Authorization] = _cred;
    

    这给了我我想要的那些标题(粘贴的 Wireshark 描述),

    授权:基本 bXlVc2VyOm15UHdk\r\n
    凭据:myUser:myPwd

    【讨论】:

    • 那么你怎么确定要使用的编码是ASCII?
    • 好点。选择的编码看起来可能是“难以找到”的错误来源。我添加链接stackoverflow.com/questions/7242316/… 供读者查找更多关于如何决定的信息。
    猜你喜欢
    • 2015-05-30
    • 2016-04-24
    • 2012-04-18
    • 2016-06-02
    • 2016-09-06
    • 2017-01-03
    • 2011-12-09
    • 1970-01-01
    相关资源
    最近更新 更多