asp.net 实现一个简单CAS Server
来源:互联网 发布:传奇霸业转生数据汇总 编辑:程序博客网 时间:2024/05/17 03:30
项目代码下载http://files.cnblogs.com/mobile/cas_demo.zip
CAS的原理,参加http://blog.csdn.net/HuDon/archive/2007/02/01/1499815.aspx
根据下图所示,我们需要实现CASClient端得"拦截器",我们通过HttpModule实现,服务端需要两个页面,一个是登陆界面,一个途中第5步通过token获取的用户信息的页面或者ashx。
1、客户端的代码和配置
新建一个类,代码如下:
HttpModule
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 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登陆后跳转而来
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判断登陆状态
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 (senderas 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
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 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登陆后跳转而来
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判断登陆状态
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 (senderas 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服务端代码
1)登陆页面
Code
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->1 <formid="form1" runat="server" method="post" action="login.ashx">
2 <div>Login ID:<inputtype="text" id="loginid" name="loginid"/></div>
3 <div>Password:<inputtype="password" id="password" name="password"/></div>
4 <div><inputtype="hidden" id="continute_url" name="continute_url" value="<%=Request["continute_url"] %>"/></div>
5 <div><inputtype="submit" value="Login"/></div>
6 </form
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->1 <formid="form1" runat="server" method="post" action="login.ashx">
2 <div>Login ID:<inputtype="text" id="loginid" name="loginid"/></div>
3 <div>Password:<inputtype="password" id="password" name="password"/></div>
4 <div><inputtype="hidden" id="continute_url" name="continute_url" value="<%=Request["continute_url"] %>"/></div>
5 <div><inputtype="submit" value="Login"/></div>
6 </form
其中continute_url是filer传来的
2)登陆代码
Login
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 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 //转移
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
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 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 //转移
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
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 1 publicclass 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
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 1 publicclass 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
运行过程基本是这样的:用户访问网站,filer首先拦截判断session中用户信息,如果不为空放行,否则,转到CAS登陆界面,登陆界面登陆后,返回地址中夹带token.
网站后台通过get或者post方法使用token去获取用户信息。
最后网站程序通过Session["user"]获取用户信息,无需关心登陆的实现,这样我们就实现了一个简单单点登录系统了。
- asp.net 实现一个简单CAS Server
- CAS实现的一个简单LinkedQueue
- 我的一个ASP.net简单查询实现
- ASP.NET三层架构的一个简单实现
- ASP.NET : 一个网站繁体转换的简单实现
- 一个简单的asp.net 单点登录实现
- ASP.NET 管道事件与HttpModule一个简单地实现
- asp.net core 实现一个简单的仓储
- 一个yale-cas实现单点登录的简单例子实现
- 简单实现asp.net进度条
- 使用ArcGIS Server和ASP.net建立一个简单的网站
- Yale CAS + .net Client 实现 SSO(3)--实现 ASP.NET WebForm Client
- 要用asp.net和sql server做一个购物网站,如何实现购物车功能啊?
- ASP.NET ATLAS 的一个简单例子
- ASP.Net生成一个简单的图片
- 一个简单的ASP.NET +ACCESS 登录
- asp.net AJAX 一个简单示例
- 一个简单的asp.net动态页面
- 24点游戏 程序(二)
- 栈---数组实现
- MacVim配置文件
- API Demos 2.3 学习笔记 (16)-- Views->Spinner
- CPU的大端模式(big endian)和小端(little endian)模式
- asp.net 实现一个简单CAS Server
- Y470 + Ubuntu10.04 博通 NetLink BCM57781 无法上网问题
- 重载数组下表操作符
- vim配置文件vimrc
- 回想寒假
- python学习心得
- 工作与梦想中的工作:给计算机专业学生的建议
- zzzBltValidBits
- Flex 4.5 Spark DataGrid 多列排序