c#应用程序页面应该使用HttpWebRequest将用户登录到不同的网站
本文关键字:登录 用户 网站 HttpWebRequest 应用程序 | 更新日期: 2023-09-27 17:50:45
我需要允许用户从我们的SharePoint 2010门户到其他由不同LDAP服务器进行身份验证的网站进行单点登录。我们不可能把它们合在一起。
我们决定将用户的凭据存储在SharePoint门户(站点a)的安全存储应用程序中。当用户想要登录到另一个站点(站点B)时,我们将使用这些凭据。站点B运行一个简单的基于表单的身份验证。我使用的是在Visual Studio 2010中运行的空ASPX页面背后的代码。
我们的想法是,我们希望用户点击链接到站点B和SharePoint发送他们的凭据为他们。
我有代码从SharePoint安全存储应用程序提取用户的凭据。但是我很难找到第二部分的例子。我正在用一个由我控制并能严密监控的测试应用测试身份验证部分。
首先,在aspx的Page_Load中,我有:
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;
}
}
我已经删除了处理请求和响应的类文件,现在只让它在page_load事件处理程序方法的主体中运行。我知道如何将服务器从目标登录站点接收到的cookie传递回去。这段代码运行和调试都很完美。
然而,我现在的问题是cookie永远不会出现在浏览器上。这是因为它们来自与服务器不同的域吗?目标登录应用程序位于xxx.test.edu,我的开发服务器是sp-developer。这会造成问题吗?我错过了什么?
我找到了一种不同的方法来做到这一点。我偶然发现了一篇文章的更清晰的版本,这一次我更好地理解了作者想要做的事情:张贴从ASP。网页到另一个URL
所以代码最终看起来像这样:
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() ;
}
}
我只是在上面定义的类上设置属性并调用Post()。
很有魅力。