网上看到很多单点登录的原理和实例,讲的像广告一样。哎,我看了好几天还是看不明白。但是项目需要这个功能,于是,我自己做了一个。发布出来,希望像我一样的需求的人能早些解决问题。
思路:使用第三方认证。那么就要用到跨域访问(就是变量要在不同ip地址下实现访问),大白话说,就是网络访问。我不会Socket,就用Remoting吧!(Application不可以,因为它不能跨主机)
看代码:
1,建类库StatusService,在它里面建类LoginList
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace StatusService
{
public class LoginList : MarshalByRefObject, IList
{
private object[] _contents = new object[8];
private int _count;
public LoginList()
{
_count = 0;
}
// IList Members
public int Add(object value)
{
if (_count < _contents.Length)
{
_contents[_count] = value;
_count++;
return (_count - 1);
}
else
{
return -1;
}
}
public void Clear()
{
_count = 0;
}
public bool Contains(object value)
{
bool inList = false;
for (int i = 0; i < Count; i++)
{
if (_contents[i] == value)
{
inList = true;
break;
}
}
return inList;
}
public int IndexOf(object value)
{
int itemIndex = -1;
for (int i = 0; i < Count; i++)
{
if (_contents[i] == value)
{
itemIndex = i;
break;
}
}
return itemIndex;
}
public void Insert(int index, object value)
{
if ((_count + 1 <= _contents.Length) && (index < Count) && (index >= 0))
{
_count++;
for (int i = Count - 1; i > index; i--)
{
_contents[i] = _contents[i - 1];
}
_contents[index] = value;
}
}
public bool IsFixedSize
{
get
{
return true;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public void Remove(object value)
{
RemoveAt(IndexOf(value));
}
public void RemoveAt(int index)
{
if ((index >= 0) && (index < Count))
{
for (int i = index; i < Count - 1; i++)
{
_contents[i] = _contents[i + 1];
}
_count--;
}
}
public object this[int index]
{
get
{
return _contents[index];
}
set
{
_contents[index] = value;
}
}
// ICollection Members
public void CopyTo(Array array, int index)
{
int j = index;
for (int i = 0; i < Count; i++)
{
array.SetValue(_contents[i], j);
j++;
}
}
public int Count
{
get
{
return _count;
}
}
public bool IsSynchronized
{
get
{
return false;
}
}
// Return the current instance since the underlying store is not
// publicly available.
public object SyncRoot
{
get
{
return this;
}
}
// IEnumerable Members
public IEnumerator GetEnumerator()
{
// Refer to the IEnumerator documentation for an example of
// implementing an enumerator.
throw new Exception("The method or operation is not implemented.");
}
public void PrintContents()
{
Console.WriteLine("List has a capacity of {0} and currently has {1} elements.", _contents.Length, _count);
Console.Write("List contents:");
for (int i = 0; i < Count; i++)
{
Console.Write(" {0}", _contents[i]);
}
Console.WriteLine();
}
}
}
2,建一个控制台SSOService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
namespace SSOService
{
class MyServer
{
[STAThread]
static void Main(string[] args)
{
RemotingConfiguration.Configure("SSOService.exe.config");
Console.ReadLine();
}
}
}
配置文件是:
<configuration>
<system.runtime.remoting>
<application name="SSOService">
<service>
<wellknown type="StatusService.LoginList,StatusService" objectUri="StatusService.LoginList"
mode="Singleton" />
</service>
<channels>
<channel ref="tcp" port="9999"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
3,网站S1文件:
Default.aspx
Login.aspx
Web.config
(1)Default.aspx内容就是:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>S2</title>
</head>
<body>
<form id="form1" runat="server">
<div>
S2登陆成功!
</div>
</form>
</body>
</html>
实际使用按照需求自由调整。
(2)Login.aspx
前台是:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>S2</title>
</head>
<body>
<form id="form1" runat="server">
<div style="line-height:30px;">
<div>s2登陆界面</div>
用户:<asp:TextBox id="user" Text="abc" runat="server"></asp:TextBox><br />
密码:<asp:TextBox ID="pwd" Text="123" runat="server"></asp:TextBox><br />
<asp:Button ID="Button1" Text="登陆" OnClick="Button1_OnClick" runat="server" />
</div>
</form>
</body>
</html>
后台是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Login : System.Web.UI.Page
{
StatusService.LoginList ls = (StatusService.LoginList)Activator.GetObject(typeof(StatusService.LoginList), System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"]);
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("记录条数是:" + ls.Count.ToString() + "<br/>");
for (int i = 0; i < ls.Count; i++)
{
//Response.Write(ls[i] + "<br/>");
if (ls[i].ToString().Trim()=="abc")
{
Response.Redirect("Default.aspx");
}
}
}
protected void Button1_OnClick(object sender, EventArgs e)
{
ls.Add("abc");
Response.Redirect("Default.aspx");
}
}
(3)Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="ServiceURL" value="tcp://localhost:9999/StatusService.LoginList"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
</configuration>
4,再建一个S2,和S1一样。
5,运行时要设置多项目运行,并且是最先运行SSOService。
完毕!
上叙是在vs2010上测试的。绝对简单实用,没有广告!不实就砸我吧,我认!有好的建议希望多赐教!谢谢了!