惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LINUX DO - 最新话题
云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
美团技术团队
V
Visual Studio Blog
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美
D
Docker
宝玉的分享
宝玉的分享
小众软件
小众软件
U
Unit 42
A
About on SuperTechFans
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
月光博客
月光博客
G
Google Developers Blog
The Cloudflare Blog
H
Help Net Security
B
Blog
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
I
Intezer
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyberwarzone
Cyberwarzone
C
Cyber Attacks, Cyber Crime and Cyber Security
Blog — PlanetScale
Blog — PlanetScale
C
Cisco Blogs
Project Zero
Project Zero
腾讯CDC
Help Net Security
Help Net Security
Latest news
Latest news
A
Arctic Wolf
T
The Exploit Database - CXSecurity.com
B
Blog RSS Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Hacker News
The Hacker News
P
Palo Alto Networks Blog
AI
AI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

博客园 - -Enchant

Linux上搭建Asp.net MVC3环境(CentOS + Nginx + Mono) 《单例模式》你需要注意的问题 系统框架整理 Extjs prompt 显示密码框 Python网页抓取、模拟登录 Jquery以JSON方式调用WebService WCF初探 关于抓取百度搜索内容 iPhone开发环境搭建(备忘) SMTP/POP3命令简介(转) C/S模式下 简单的定时任务功能 Asp.net MVC2学习笔记索引 Oracle 调优 Oracle常见错误 @OutputCache指令参数 关于ACL权限控制【ASP.NET MVC2】 c#递归生成XML ASP.NET MVC2 Ajax返回JSON 引用类型的对象复制(浅复制和深复制)
单点登录(SSO)的一点思考
-Enchant · 2010-09-21 · via 博客园 - -Enchant

这几天稍微关注了一下SOA方面的资料,抛开webservice性能问题不说,就当当这验证问题就让人头疼

考虑到几点:

1、调用方法的时候把用户名密码都带上,显然不太理想,每次都需要传递密码也不太那个安全,而且每次都要验证用户名和密码正确性,麻烦

2、不把用户名和密码带上,怎么知道这次来连接的是谁呢?

由上面2个问题,突然考虑到单点登录,我只登录一次,只把用户和密码传递一次不就行了嘛,听起来不错,可是问题又来了,你下次调用的时候

我怎么知道你已经登录并且有权限呢?于是考虑到 在第一次登录成功的时候返回给你一串加密的字符串,以后你每次来调用我方法的时候,带上

这个已经验证过的字符串不就可以了嘛,听起来还是不错,可是每次调用方法的时候都必须带上这串字符串岂不是还是很累赘?

暂时不考虑那么多了,就怎么先实现以下吧,希望高手们多多给建议。。。

稍微画了下图:

客户端首先需要调用Login方法,去验证服务器(SSO Server)验证,成功后携带ssokey返回,SsoServer保存登陆成功的用户。

客户端调用应用服务器方法时必须携带ssokey,以便应用服务器验证用户是否登陆。

关于 Application Server 和 SSO Server 如何通讯,我想有多种方式可以解决,比如说 Remoting/WebService/Wcf 等。。。。。

当然我们也可以把验证服务器和应用程序服务器放到一台服务器上。。。。

下面就可以通过具体代码来实现了:

为了方便,这里我采用webservice方式来通讯,我建立2个webserviice

  1、SSOServer.asmx

  2、MyApplicationService.asmx

这里 使我的应用也以 webservice的形式发布(SOA嘛。。)

  1、SSOServer.asmx代码如下,其中只包括了 Login(登陆) 和 IsLogin(验证是否已经登录)方法

1 using System;
2  using System.Collections.Generic;
3  using System.Linq;
4  using System.Web;
5  using System.Web.Services;
6
7  namespace SSOTest
8 {
9 /// <summary>
10 /// SSOServer 的摘要说明
11 /// </summary>
12   [WebService(Namespace = "http://tempuri.org/")]
13 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
14 [System.ComponentModel.ToolboxItem(false)]
15 // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
16   [System.Web.Script.Services.ScriptService]
17 public class SSOServer : System.Web.Services.WebService
18 {
19 //key:用户名 value:ssokey
20   public static Dictionary<string, string> onlineUser = new Dictionary<string, string>();
21
22 [WebMethod]
23 public string Login(string userName, string passWord)
24 {
25 //验证用户名密码
26   if ("huwei".Equals(userName))
27 {
28 //
29   if (onlineUser.ContainsKey(userName))
30 {
31 onlineUser.Remove(userName);
32 }
33
34 //成功后生成新的ssokey并返回
35   string ssokey = Guid.NewGuid().ToString();
36
37 onlineUser.Add(userName,ssokey);
38 return ssokey;
39 }
40 return "";
41 }
42
43 //判断是否已经登录
44   [WebMethod]
45 public bool IsLogin(string ssokey)
46 {
47 return onlineUser.ContainsValue(ssokey);
48 }
49 }
50 }
51  

这里只是简单的测试一下,实际上还有很多需要考虑的因素,比如说 你的 ssokey 保存的时间,总不至于ssokey一直保存着吧

   2、MyApplicationService.asmx

1 using System;
2  using System.Collections.Generic;
3  using System.Linq;
4  using System.Web;
5  using System.Web.Services;
6  using System.Web.Script.Services;
7
8  namespace SSOTest
9 {
10 /// <summary>
11 /// MyApplicationService 的摘要说明
12 /// </summary>
13   [WebService(Namespace = "http://tempuri.org/")]
14 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
15 [System.ComponentModel.ToolboxItem(false)]
16 // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
17   [System.Web.Script.Services.ScriptService]
18 public class MyApplicationService : System.Web.Services.WebService
19 {
20 [WebMethod]
21 [ScriptMethod(ResponseFormat=ResponseFormat.Json,UseHttpGet=true)]
22 public string TestMethod(string ssokey)
23 {
24 SSOServer server = new SSOServer();
25 if (server.IsLogin(ssokey))
26 {
27 Console.WriteLine("恭喜!认证成功!");
28
29 try
30 {
31 MySqlHelper helper = new MySqlHelper();
32 helper.Execute("insert into Friends (firstname,lastname,age,email) values ('fff','lll',22,'aaeeee')");
33 }
34 catch (Exception e)
35 {
36 Console.WriteLine(e.Message);
37 }
38
39 return "恭喜!认证成功!";
40 }
41 else
42 {
43 Console.WriteLine("抱歉!认证失败!请重新登录");
44 return "抱歉!认证失败!请重新登录";
45 }
46 }
47 }
48 }
49  

  3、前台测试一下,采用jquery ajax 来登录,并执行方法

    在 Default.aspx 页面中加入如下脚本

1 <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
2   <script type="text/javascript">
3 var ssokey = "";
4
5 function doLogin(userName, passWord) {
6 $.ajax({
7 url: "http://localhost:11143/SSOServer.asmx/Login",
8 type: "post",
9 data: "username=" + userName + "&passWord=" + passWord,
10 success: function (data) {
11 //alert($(data).find("string").text());
12   ssokey = $(data).find("string").text();
13 alert("登录成功");
14 }
15 });
16 }
17
18 function doJSON() {
19 $.ajax({
20 url: "http://localhost:11143/MyApplicationService.asmx/TestMethod",
21 data: {ssokey:"'" + ssokey + "'"},
22 dataType: "JSON",
23 contentType: "application/json; charset=utf-8",
24 success: function (data) {
25 alert(data);
26 }
27 });
28 }
29 </script>

这里写了 2个方法,一个是登陆方法,首先必须要先登陆获得 ssokey,然后才能成功的执行 方法 

总结:

这种方式我觉得还是不太好,毕竟每次执行方法都要检测ssokey是否已经登录,肯定存在浪费的情况,不知道各位高手有没有更好的解决方案。