C#应用程序页面应使用HttpWebRequest将用户登录到其他网站
我有一个要求,允许用户从我们的SharePoint 2010门户SSO到其他通过不同LDAP服务器验证的网站。我们将无法将它们组合在一起 我们已确定将用户凭据存储在SharePoint门户(站点a)中的安全存储应用程序中。当用户想要登录到另一个站点(站点B)时,我们将使用这些凭据。站点B运行一个简单的基于表单的身份验证。我正在Visual Studio 2010中运行的空ASPX页面后面使用代码 我们的想法是希望用户单击指向站点B的链接,然后SharePoint为他们发送凭据 我拥有从SharePoint Secure Store应用程序提取用户凭据的代码。但我很难找到第二部分的工作示例。我正在用一个我能控制并能严密监控的测试应用程序测试身份验证 首先,在aspx的页面加载中,我有:C#应用程序页面应使用HttpWebRequest将用户登录到其他网站,c#,authentication,sharepoint,sharepoint-2010,C#,Authentication,Sharepoint,Sharepoint 2010,我有一个要求,允许用户从我们的SharePoint 2010门户SSO到其他通过不同LDAP服务器验证的网站。我们将无法将它们组合在一起 我们已确定将用户凭据存储在SharePoint门户(站点a)中的安全存储应用程序中。当用户想要登录到另一个站点(站点B)时,我们将使用这些凭据。站点B运行一个简单的基于表单的身份验证。我正在Visual Studio 2010中运行的空ASPX页面后面使用代码 我们的想法是希望用户单击指向站点B的链接,然后SharePoint为他们发送凭据 我拥有从Share
CookieContainer cookieContainer = new CookieContainer();
// Create a request using a URL that can receive a post.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://test.edu/admin_login.cfm") as HttpWebRequest;
request.CookieContainer = cookieContainer;
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "userName=testUser&password=testPW&login=Login";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
StreamReader reader = new StreamReader(response.GetResponseStream());
string tmp = reader.ReadToEnd();
foreach (Cookie cook in response.Cookies)
{
Response.Cookies.Add(CookieToHttpCookie(cook));
}
下面是我用来转换为HTTPCookie的代码:
public System.Web.HttpCookie CookieToHttpCookie(Cookie cookie)
{
System.Web.HttpCookie httpCookie = new System.Web.HttpCookie(cookie.Name);
/*Copy keys and values*/
foreach (string value in cookie.Value.Split('&'))
{
string[] val = value.Split('=');
if (0 < val.Length)
{
httpCookie.Values.Add(val[0], null);
}
else
{
httpCookie.Values.Add(val[0], val[1]);
}
}
/*Copy Porperties*/
httpCookie.Domain = cookie.Domain;
httpCookie.Expires = cookie.Expires;
httpCookie.HttpOnly = cookie.HttpOnly;
httpCookie.Path = cookie.Path;
httpCookie.Secure = cookie.Secure;
return httpCookie;
}
}
public System.Web.HttpCookie CookietOhtpcookie(Cookie Cookie)
{
System.Web.HttpCookie-HttpCookie=new-System.Web.HttpCookie(cookie.Name);
/*复制键和值*/
foreach(cookie.value.Split('&')中的字符串值)
{
字符串[]val=value.Split('=');
如果(0
我已经删除了处理请求和响应的类文件,现在只让它在page_load事件处理程序方法的主体中运行。我了解如何传回服务器从目标登录站点收到的cookies。这段代码可以完美地运行和调试
然而,我现在的问题是cookies从未出现在浏览器上。这是因为它们来自与服务器不同的域吗?目标登录应用程序位于xxxx.test.edu,我的开发服务器是sp developer。这会引起问题吗?我错过了什么?我找到了一种不同的方法。我无意中看到了一篇较清晰的文章,这篇文章是我前段时间直接读到的,这次我更清楚地理解了作者的意图: 因此,代码最终如下所示:
public class RemotePost{
private System.Collections.Specialized.NameValueCollection Inputs
= new System.Collections.Specialized.NameValueCollection() ;
public string Url = "" ;
public string Method = "post" ;
public string FormName = "form1" ;
public void Add( string name, string value ){
Inputs.Add(name, value ) ;
}
public void Post(){
System.Web.HttpContext.Current.Response.Clear() ;
System.Web.HttpContext.Current.Response.Write( "<html><head>" ) ;
System.Web.HttpContext.Current.Response.Write( string .Format( "</head><body onload=\"document.{0}.submit()\">" ,FormName)) ;
System.Web.HttpContext.Current.Response.Write( string .Format( "<form name=\"{0}\" method=\"{1}\" action=\"{2}\" >" ,
FormName,Method,Url)) ;
for ( int i = 0 ; i< Inputs.Keys.Count ; i++){
System.Web.HttpContext.Current.Response.Write( string .Format( "<input name=\"{0}\" type=\"hidden\" value=\"{1}\">" ,Inputs.Keys[i],Inputs[Inputs.Keys[i]])) ;
}
System.Web.HttpContext.Current.Response.Write( "</form>" ) ;
System.Web.HttpContext.Current.Response.Write( "</body></html>" ) ;
System.Web.HttpContext.Current.Response.End() ;
}
}
公共类RemotePost{
专用System.Collections.Specialized.NameValueCollection输入
=新System.Collections.Specialized.NameValueCollection();
公共字符串Url=“”;
公共字符串Method=“post”;
公共字符串FormName=“form1”;
公共void添加(字符串名称、字符串值){
输入。添加(名称、值);
}
公共空缺职位(){
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.Write(“”);
System.Web.HttpContext.Current.Response.Write(string.Format(“,FormName));
System.Web.HttpContext.Current.Response.Write(string.Format(““”),
表单名称、方法、Url);
对于(int i=0;i
我只是在上面定义的类上设置属性并调用Post()
工作起来很有魅力 更新:我发现上面的Post()方法和一些使用HttpWebRequest=(HttpWebRequest)WebRequest.Create(“”)的代码;正在获取System.NotSupportedException。Microsoft表示需要注册RequestUristing中指定的请求方案。知道这意味着什么吗?我已经改进了代码,现在我对C#中的cookie处理有了更好的理解,因为代码充当客户端和服务器。我唯一的问题是cookie不可用't现在不会出现在浏览器中,尽管我没有发现以下行有任何问题:Response.Cookies.Add(CookieToHttpCookie(cook));我似乎记得你可以拥有无cookie的cookies…这仍然让你拥有cookies,但它们没有保存到驱动器中,而是编码在URL中,也许这就是为什么你看不到cookies,但它仍然工作的原因。