您的位置:首页 > 编程语言 > ASP

asp.net 实现一个简单CAS Server

2012-02-26 14:05 627 查看
项目代码下载
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. href="http://www.haogongju.net/tag/com" target=_blank>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 (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服务端代码
1)登陆页面




Code

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->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

<!--

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 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

运行过程基本是这样的:用户访问网站,filer首先拦截判断session中用户信息,如果不为空放行,否则,转到CAS登陆界面,登陆界面登陆后,返回地址中夹带token.
网站后台通过get或者post方法使用token去获取用户信息。

最后网站程序通过Session["user"]获取用户信息,无需关心登陆的实现,这样我们就实现了一个简单单点登录系统了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: