单点登录解决方案

网上看到很多单点登录的原理和实例,讲的像广告一样。哎,我看了好几天还是看不明白。但是项目需要这个功能,于是,我自己做了一个。发布出来,希望像我一样的需求的人能早些解决问题。

思路:使用第三方认证。那么就要用到跨域访问(就是变量要在不同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上测试的。绝对简单实用,没有广告!不实就砸我吧,我认!有好的建议希望多赐教!谢谢了!

posted @ 2012-01-03 12:02  szjdw  阅读(674)  评论(0编辑  收藏  举报