单点登陆通用类

说明

自从上次的《偷懒小工具 - Excel导出》发布之后,看阅读量还能够,就决定继续分享一下其余方面的帮助类。html

风格仍是相似的极简风,登陆方法,调用的代码尽可能超过三行,而后搞定一切。源代码参考文章最下方。git


同域和跨域

a.baidu.com 中。a 是二级域名,baidu 是一级域名。一样的一级域名是能够共享Cookie的。github

不一样一级域名,由于同源策略缘由,不能共享Cookie。也就是跨域算法

例如:微信扫码登陆,就是这种跨域的实用例子跨域

a.baidu.com 和 b.baidu.com 是能够共享cookie,也就是同域。缓存

www.baidu.com 和 www.qq.com 就属于跨域。安全

单点登陆

SSO 单点登陆,主要就是使用统一的身份验证模块,而后各网站共享身份验证。微信

也就是只登陆一次,其余网站都可免登录。cookie

关于身份验证方面,各位若有疑惑可自行百度。或者看一下,我记录的 《ASP.NET身份认证》函数

(是给本身看的可能有些乱)

由于同源策略的问题,因此同域和跨域方法实现差距比较大。

我这边根据同域和跨域,这两种不一样状况,分享两个帮助类。

这两个帮助类,互相独立。各位按照本身的需求选择查看使用。

(由于就一我的精力有限,白天还要上班,没有进行太多测试)设计不合理或者BUG,确定会有一些。

流程图

首先,看一下同域的流程图。

 

再看一下,跨域的流程图

看着,很简单吧。我相信大家确定能够看懂,我就不做解释了。下面看使用。

使用步骤

配置

这里WebConfig,采用了以下的配置。

WebConfig

用户认证网站,直接使用~/Login.aspx 指向本身的登陆页面。

其余网站,使用 “认证网站地址”+?link+“本网站地址”。这种方式,来进行登陆后的跳转。

同域

共同一级域名的状况。可使用SSOGeneralSameDomain类,进行登陆。

  1. 首先,须要你自行制做一个登陆界面,自行进行用户名和密码的验证
  2. 调用以下方法。
MVC登陆

其中,Login就是用户登陆方法。一共两行代码。name 参数是你须要保存的数据。

其中,Index方法,能够得到你保存的用户名。(这里为了方便使用的明文用户名)

WebForm登陆

WebForm登陆方式是同样的,这里不作过多描述。

调用 SSOGeneralSameDomain.LogUp(); 可进行用户注销。

此时你的网站,就能够共享身份验证了。

跨域

不一样一级域名的状况。可使用SSOGeneralCrossDomain类,进行登陆

  1. 首先,须要自行制做一个登陆界面。这个无法省略,或者你直接用我示例代码的登陆。
  2. 认证网站,调用LogIn方法。其余网站,调用LogInClient方法。
认证网站登陆

须要传递:保存的数据、Cookie名称、保存时长

其余网站登陆

须要传递:认证网站地址、Cookie名称、保存时长

此时,你就能够完成跨域单点登陆了。可是注意,认证网站,还须要调用一个验证方法。

验证方法

思路和过程

同域 

分析

同域的思路比较简单,也相对来讲比较好实现。有两点要考虑的(若是有其余办法,请留言

  1. Request 和 Response 的操做问题
  2. 其余网站的登陆后跳转问题

Request 操做:由于Mvc和WebForm的Request,存在于两个不一样的类(HttpContextBase和Page)。

  这个找了半天,也没有想到能公用的办法,因而就用抽象工厂来搞了一下。

跳转问题:由于Forms身份认证的ReturnUrl参数,只能拿到文件,而不能拿到网址。因此无法跳转到对应网站。

  这个我在博问上试着问了一下,结果有一个大哥说:你要这么多干啥,没啥用。当时我就懵逼了!!!

     后来,没有找到什么好办法,就用的笨办法,也就是使用link进行跳转。

作法

这两个问题解决了,咱们接下来看看代码。仍是向上次同样,一步一步来讲一下。

作Request和Response操做封装

首先,建立一个抽象类,而后把须要的方法封装一下,接着定义Page和HttpContext两个子类,继承实现

Operation
OperationHttpContext
OperationPage

作同域单点登陆的类

1. 首先,分析一下每一个登陆,都须要名字和过时时间,那么这俩字段上移。 确定都得有登陆方法,那么方法上移。

SSOGeneral

这里字段Set 私有,也是安全性的考虑。我在初始化的时候,就传递这两个参数。 

2. 接着,建立 SSOGeneralSameDomain 类,继承抽象类。

定义私有字段,Operation用来执行操做。构造函数中对这个字段进行赋值。

构造函数

实现抽象类的LogIn方法。这个方法只有三步:1.建立Forms认证票据。2.保存到Cookie中。3.成功后跳转。

Login
Create

CreateTicket 和 CreateCookie 方法逻辑很是简单,我就不说明了。说一下跳转逻辑。 

RedirectPage

有link 找link,没有找ReturnUrl,再没有直接跳转到根目录。 至此登陆作完了。

3. 最后,作注销和获取内容方法。这边为了方便,使用静态类实现的。

注销都是固定的方法,获取内容,就是拿Cookies。而后解密

Static

同域的帮助类,至此就算完成了。

跨域

跨域真的是比较纠结的一点,由于我懒,因此通常都是先上网找相关文章。

发现,文章有用的很是少。一些伪跨域的特别多,有些卡卡卡说一大堆,结果发现不一样的是二级域名。

还有就是使用 接口,来回传信息的。由于我想作帮助类,用接口的话就耦合在一块儿了。不太想用。

PS:找了一天,最后烦躁了不找了,开始本身想本身研究。

分析

实际上同域须要处理的地方,就是传递凭证。接收到凭证之后,就会进行本地存储,因此传递是终点。

跨域须要考虑的点,就比较多了,除了同域的问题还有如下几点:(若是有其余办法,请留言

  1. Cookie不能共享,如何验证信息
  2. 如何处理登陆用户的持久化
  3. 登陆和认证要用什么形式展示

Cookie不能共享:使用Token做为凭据传递,可根据Token获取保存信息。

持久化:提供持久化接口,任何方式只要知足此接口便可。我这里提供了Http缓存和Cookies方法。

登陆和认证:流程跟上面的图差很少。主要开放五个方法:

LogIn(登陆)、LogInClient(其余网站登陆)、ValidationToken(认证)、GetUserData(获取登陆内容)、LogUp(注销)

作法

1. 首先,仍是跟同域同样作Operation 而后Page 和 HttpContextBase继承这个Operation

Operation
OperationPage
OperationHttpContext

2. 由于会有凭证的传递,因此咱们还须要一个加密。这里,我给出一个接口,并给出了DES加密的实现方法。

  各位能够按照本身想进行的加密逻辑,自行扩展。

IOperationSecret
OperationSecret

3. 持久层也是必不可少的,用来存放已经登陆的用户信息。这里也是给出的接口。并给出了Cookie 和 Cache的操做方法

  各位能够按照本身想实现的持久层,进行处理。

IOperationToken
OperationCookies

CreateToken 生成凭证的这个方法。我这边采用最简单的GUID进行生成的,这种无规律的是没有办法伪造的。

SetToken的UserData,使用的就是上方的加密认证。

我以为只要涉及到HTTP传递,就确定能拦截,因此重点应该是怎么不让他破解。加密算法,各位能够自行实现。

OperationCache
public class SSOToken
    {
        public string UserData { get; set; } public string Token { get; set; } public DateTime OverdueTime { get; set; } }

持久层存储模型,就使用这个必不可少的几个字段进行存储。

4. 跨域单点登陆类,由于这个类比较复杂,因此我不想提太多公共方法或字段。

SSOGeneral

建立SSOGeneralCrossDomain类,咱们把参数都做为属性提出来,而后把接口也进行提取。

构造函数

咱们看一下LogIn 登陆方法是如何实现的。

LogIn

这个方法,是认证中心点击保存之后执行的方法。

先进行SetToken 把登陆信息存到持久层。而后返回对应的Token。

接着进行GetRedirectUrl。这个方法获取咱们登陆成功后,将要跳转的地址。

GetRedirectUrl

接下来的,跟同域的状况同样。这里就很少说了。咱们如今已经实现了,认证中心的登陆。接下来,咱们制做其余网站的登陆。

其余网站,使用此功能,也要定义本身的Login.aspx页面,只是在这个页面调用这个方法。

LogInClient

咱们先判断,是登陆仍是认证。好比:咱们没有登陆,打开网站A,这种状况就是登陆。网站A登陆后,跳转到网站B,这种状况就是认证

IsLogin

接下来咱们验证Token,这一步很重要。这一步能够把网站引导到认证中心,或者自动认证。

ValidationToken
  1. 首先,咱们认为没有传递凭证 就是须要登陆。UserData 是已经认证完毕的内容。
  2. 咱们判断是否同域,由于Cookie只有在一个域下才能够调用。
  3. 咱们把当前的地址信息封装,引导到认证中心进行认证。
  4. 没有进行验证的都会在这一步卡住。

接下来,就是显而易见的 解密、本地存储了。很简单很少讲了。

GetUserData 和 LogUp。一个是获取本地Cookie,一个是注销登陆(跟同域操做同样)

至此,咱们的单点登陆,所有搞定。接下来,咱们进行测试。

测试

同域

首先,咱们建立两个认证中心。一个MVC的,一个WebForm的。而后Web建立2个网站,MVC建立1个。用来作跳转。

Authorize 认证中心,使用的是MVP 的PV模式。首先咱们给Web相关的网站,定义统一的Web.Config

WebConfig

同域状况下,Web1\2 登陆地址均指向 Authorize

接下来,在登陆后调用方法

Login

咱们在 Web1 里面写一下获取方法 和 注销

Web1

这个时候,咱们Web1设为启动项。而后就能够测试了。具体页面,我就不粘贴了。能够参考下方源码

跨域

跨域须要在各个应用底下,建立本身的Login.aspx登陆页面。而后调用这个方法,或者你建立主页调用同样。

Web1网站 调用方法以下

Login

加载内容以下

Page_Load

Authorize网站,调用方法以下

认证网站

在Initialize 初始化的时候,添加验证方法。这样能够接受其余网站发送的验证请求。

在登陆页面,直接调用登陆方法便可。

具体测试项目,都在Github上。各位能够自行下载。 

源码地址:https://github.com/chenxygx/SSOGeneral

相关文章
相关标签/搜索