項目代碼下載 http://files.cnblogs.com/mobile/cas_demo.zip
CAS的原理,參加 http://blog.csdn.net/HuDon/archive/2007/02/01/1499815.aspx
根據(jù)下圖所示,我們需要實現(xiàn)CASClient端得"攔截器",我們通過HttpModule實現(xiàn),服務(wù)端需要兩個頁面,一個是登陸界面,一個途中第5步通過token獲取的用戶信息的頁面或者ashx。
1、客戶端的代碼和配置
新建一個類,代碼如下:

HttpModule
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.SessionState;
6 using System.Text;
7 using System.Net;
8 using System.IO;
9
10 namespace client
11 {
12 public class filter : IHttpModule, IRequiresSessionState
13 {
14 string login_url = "http://localhost:10888/Default.aspx";
15 string verify_url = "http://localhost:10888/method.ashx";
16
17 public void Dispose()
18 {
19
20 }
21
22 public void Init(HttpApplication context)
23 {
24 context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
25 }
26
27 void context_PreRequestHandlerExecute(object sender, EventArgs e)
28 {
29 try
30 {
31 HttpApplication ha = (HttpApplication)sender;
32
33 HttpRequest Request = ha.Context.Request;
34 HttpResponse Response = ha.Context.Response;
35
36 string continue_url = Request.Url.AbsoluteUri;
37 string path = ha.Context.Request.Url.AbsolutePath;
38
39
40 string token = Request["token"];
41 if (!string.IsNullOrEmpty(token)) //這次請求是從CAS登陸后跳轉(zhuǎn)而來
42 {
43 //使用POST連接CAS的method.ashx,通過token獲取用戶信息
44 string res = Post(verify_url, "token=" + token, "utf-8");
45 ha.Session["user"] = res;
46 Response.Redirect(ha.Session["continue_url"].ToString());
47 }
48
49 if ((ha.Session == null) || (ha.Session["user"] == null)) //通過Session判斷登陸狀態(tài)
50 {
51 ha.Session["continue_url"] = continue_url;
52 ha.Response.Redirect(login_url + "?continute_url=" + continue_url); //去登陸cas頁面
53 }
54 }
55 catch (Exception ex)
56 {
57 (sender as HttpApplication).Response.Write(ex.Message);
58 }
59 }
60
61 public string Post(string postUrl, string postData, string chars_set)
62 {
63 Encoding encoding = Encoding.GetEncoding(chars_set);
64 HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(postUrl);
65 CookieContainer cookieContainer = new CookieContainer();
66 Request.CookieContainer = cookieContainer;
67 Request.Method = "POST";
68 Request.ContentType = "application/x-www-form-urlencoded";
69 Request.AllowAutoRedirect = true;
70 byte[] postdata = encoding.GetBytes(postData);
71 using (Stream newStream = Request.GetRequestStream())
72 {
73 newStream.Write(postdata, 0, postdata.Length);
74 }
75 using (HttpWebResponse response = (HttpWebResponse)Request.GetResponse())
76 {
77 using (Stream stream = response.GetResponseStream())
78 {
79 using (StreamReader reader = new StreamReader(stream, encoding, true))
80 {
81 return reader.ReadToEnd();
82 }
83 }
84 }
85 }
86 }
87 }
88
需要在攔截所有請求,在web.config中配置
<httpModules>
..............
<add name="LoginMoudle" type="client.filter"/> //type由于寫在項目中只需要namespace.class方式,如果放在dll中,需要加",dll文件名"
</httpModules>
2、CAS服務(wù)端代碼
1)登陸頁面

Code
1 <form id="form1" runat="server" method="post" action="login.ashx">
2 <div>Login ID:<input type="text" id="loginid" name="loginid" /></div>
3 <div>Password:<input type="password" id="password" name="password" /></div>
4 <div><input type="hidden" id="continute_url" name="continute_url" value="<%=Request["continute_url"] %>"/></div>
5 <div><input type="submit" value="Login" /></div>
6 </form
其中continute_url是filer傳來的
2)登陸代碼

Login
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Services;
6
7 namespace cas
8 {
9 [WebService(Namespace = "http://tempuri.org/")]
10 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
11 public class login : IHttpHandler
12 {
13
14 public void ProcessRequest(HttpContext context)
15 {
16 HttpRequest Request = context.Request;
17 string loginid = Request["loginid"];
18 string password = Request["password"];
19 string continute_url = Request["continute_url"];
20
21 //用戶登錄驗證



.
22
23 string token = DateTime.Now.Ticks.ToString();//登陸成功后 生成token方法,自己考慮,需唯一
24 //緩存token
25 context.Application[token] = "用戶名"; //實際使用中存放用戶信息類的實例
26 //轉(zhuǎn)移
27 context.Response.Redirect(continute_url + "?token=" + token);
28 }
29
30 public bool IsReusable
31 {
32 get
33 {
34 return false;
35 }
36 }
37 }
38 }
39
3)CAS端獲取用戶信息的頁面

method GetUser
1 public class method : IHttpHandler
2 {
3
4 public void ProcessRequest(HttpContext context)
5 {
6 string token = context.Request["token"];
7
8 string user = context.Application[token].ToString(); //獲取token映射的用戶信息
9 context.Application.Remove(token); //刪除緩存的token,token一次有效
10
11 context.Response.Write(user);//實際使用中可能需要返回xml或者json格式的用戶信息
12 }
13
14 public bool IsReusable
15 {
16 get
17 {
18 return false;
19 }
20 }
21
運行過程基本是這樣的:用戶訪問網(wǎng)站,filer首先攔截判斷session中用戶信息,如果不為空放行,否則,轉(zhuǎn)到CAS登陸界面,登陸界面登陸后,返回地址中夾帶token.
網(wǎng)站后臺通過get或者post方法使用token去獲取用戶信息。
最后網(wǎng)站程序通過Session["user"]獲取用戶信息,無需關(guān)心登陸的實現(xiàn),這樣我們就實現(xiàn)了一個簡單單點登錄系統(tǒng)了。