Pet*_*ter 4 c# authentication httpwebrequest .net-3.5
我正在尝试编写将对网站wallbase.cc进行身份验证的代码.我看过使用Firfebug/Chrome Developer工具做了什么,看起来相当简单:
将"usrname = $ USER&pass = $ PASS&nopass_email = Type + in + your + e-mail + + + press + enter&nopass = 0"发布到网页"http://wallbase.cc/user/login",存储返回的cookie和在将来的所有请求中使用它们.
这是我的代码:
private CookieContainer _cookies = new CookieContainer();
//......
HttpPost("http://wallbase.cc/user/login", string.Format("usrname={0}&pass={1}&nopass_email=Type+in+your+e-mail+and+press+enter&nopass=0", Username, assword));
//......
private string HttpPost(string url, string parameters)
{
try
{
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
//Add these, as we're doing a POST
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
((HttpWebRequest)req).Referer = "http://wallbase.cc/home/";
((HttpWebRequest)req).CookieContainer = _cookies;
//We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parameters);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length); //Push it out there
os.Close();
//get response
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return null;
using (Stream st = resp.GetResponseStream())
{
System.IO.StreamReader sr = new System.IO.StreamReader(st);
return sr.ReadToEnd().Trim();
}
}
}
catch (Exception)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
在使用我的登录参数调用HttpPost之后,我希望将来使用相同方法的所有调用都要进行身份验证(假设有效的用户名/密码).我在我的cookie集合中获得了一个会话cookie但由于某种原因我没有经过身份验证.我在我的cookie集合中获得了一个会话cookie,无论我访问哪个页面,所以我尝试首先加载主页以获取初始会话cookie,然后登录但没有变化.
据我所知,这个Python版本有效:https://github.com/sevensins/Wallbase-Downloader/blob/master/wallbase.sh(第336行)
有关如何使身份验证工作的任何想法?
更新#1
使用正确的用户/密码对时,响应会自动重定向到引荐来源,但是当收到错误的用户/传递对时,它不会重定向并返回错误的用户/密码对.基于此,似乎认证正在发生,但也许并非所有关键信息都被保存?
更新#2
我使用的是.NET 3.5.当我在.NET 4中尝试上面的代码时,添加了一行System.Net.ServicePointManager.Expect100Continue = false
(在我的代码中,这里没有显示)它可以工作,不需要进行任何更改.问题似乎直接源于一些pre-.Net 4问题.
这是基于我的一个项目的代码,以及从各种答案中找到的代码stackoverflow
.
首先,我们需要设置一个Cookie aware WebClient
将要使用的HTML 1.0
.
public class CookieAwareWebClient : WebClient
{
private CookieContainer cookie = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.ProtocolVersion = HttpVersion.Version10;
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = cookie;
}
return request;
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们设置处理该代码Authentication
然后最终加载的代码response
.
var client = new CookieAwareWebClient();
client.UseDefaultCredentials = true;
client.BaseAddress = @"http://wallbase.cc";
var loginData = new NameValueCollection();
loginData.Add("usrname", "test");
loginData.Add("pass", "123");
loginData.Add("nopass_email", "Type in your e-mail and press enter");
loginData.Add("nopass", "0");
var result = client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData);
string response = System.Text.Encoding.UTF8.GetString(result);
Run Code Online (Sandbox Code Playgroud)
我们可以使用HTML Visualizer
内置的方法尝试这一点,Visual Studio
同时保持调试模式并使用它来确认我们能够authenticate
在停留时加载主页authenticated
.
这里的关键是设置CookieContainer
和使用HTTP 1.0
,而不是1.1
.我不完全确定为什么强制它使用1.0
允许您成功验证和加载页面,但解决方案的一部分是基于这个答案.
/sf/answers/764121011/
我使用Fiddler确保发送的响应C# Client
与我的Web浏览器相同Chrome
.它还允许我确认是否C# client
正确重定向.在这种情况下,我们可以看到,HTML 1.0
我们正在获取HTTP/1.0 302 Found
,然后按预期将我们重定向到主页.如果我们切换回来,HTML 1.1
我们将获得一个HTTP/1.1 417 Expectation Failed message
代替.
此stackoverflow线程中提供了有关此错误消息的一些信息. HTTP POST返回错误:417"期望失败."
编辑:Hack/Fix for .NET 3.5
我花了很多时间试图找出3.5和4.0之间的差异,但我真的不知道.看起来3.5在验证后创建了一个新的cookie,我发现的唯一方法就是对用户进行两次身份验证.
我还必须根据这篇文章中的信息对WebClient进行一些更改. http://dot-net-expertise.blogspot.fr/2009/10/cookiecontainer-domain-handling-bug-fix.html
public class CookieAwareWebClient : WebClient
{
public CookieContainer cookies = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
var httpRequest = request as HttpWebRequest;
if (httpRequest != null)
{
httpRequest.ProtocolVersion = HttpVersion.Version10;
httpRequest.CookieContainer = cookies;
var table = (Hashtable)cookies.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cookies, new object[] { });
var keys = new ArrayList(table.Keys);
foreach (var key in keys)
{
var newKey = (key as string).Substring(1);
table[newKey] = table[key];
}
}
return request;
}
}
var client = new CookieAwareWebClient();
var loginData = new NameValueCollection();
loginData.Add("usrname", "test");
loginData.Add("pass", "123");
loginData.Add("nopass_email", "Type in your e-mail and press enter");
loginData.Add("nopass", "0");
// Hack: Authenticate the user twice!
client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData);
var result = client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData);
string response = System.Text.Encoding.UTF8.GetString(result);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2532 次 |
最近记录: |