的设计与实践 网络单点登录
序
最近在群晨会上轮到我分享知识点,突然想到单点登录,准备分享一下如何实现单点登录,所以有以下几点。实施方案和代码可能不是很严格,如有漏洞或错误欢迎指正。
开始的时候,我脑子里没有任何想法。我在博客公园直接看别人是怎么实现的。看了几篇文章,发现解决方案有问题,或者不是单点登录
名称定义
为了便于解释,先解释一下文中出现的几个名词的意思:
p站:统一登录授权验证中心,演示中的域名为www.passport.com:801
站A:测试不同域名下的网站。演示中的域名是www.a.com:802
哔哩哔哩:测试不同域名下的网站。演示中的域名是www.b.com:803
令牌:用户访问P站的密钥
票证:用于保存用户信息的加密字符串
单点登录
如果需要登录访问A站,跳转到P站登录。P站登录后,跳转回a站,用户可以再次访问哔哩哔哩需要登录的页面。用户无需登录即可正常访问。
实现理念
未注册用户访问A站时,会重定向跳转到P站授权中心,P站首先通过检测Cookie判断自己当前不处于登录状态,然后跳转到登录页面进行登录操作。成功登录后,他将用户信息的加密票据附加到A请求的地址并返回。站A通过解密票证获取用户信息,解密成功并存储在Session中(使用户在A中处于登录状态),访问通过;当用户再次访问哔哩哔哩时,就哔哩哔哩而言,用户没有登录,所以它也会重定向并跳转到P站的授权中心,P站检测到Cookie并判断当前用户登录,然后将当前用户信息加密成票证并附加到B站的请求地址进行返回。后续操作与A站相同;这样,登录后,再次访问a或b,用户信息存储在a和b的Session中,因此不会再次请求p站。
简单示意图
泳道流程图
主要逻辑描述
站a的主逻辑
用户首先访问站点a,令牌将在站点a中生成并存储在缓存中。Token是A访问P的密钥,P回叫A时需要携带这个Token,A请求P,P验证Token,P回叫A,A检测Token是否发出,验证后Token变为无效,防止Token再次被使用。
令牌是在时间戳的不同字段通过MD5加密生成的,当然这里可以加一个盐进行防伪。
///summary///generate secret key///summary///param name=' timestamp '/param///returns/returns public static string create token(datetime timestamp){ StringBuilder security key=new StringBuilder(MD5 encyppt)(timestamp。ToString(' yyyy '));安全性。追加(MD5Encypt(时间戳。ToString(' MM '));安全性。追加(MD5Encypt(时间戳。ToString(' DD '));安全性。追加(MD5Encypt(时间戳。ToString(' HH '));安全性。追加(MD5Encypt(时间戳。ToString(' mm '));安全性。追加(MD5Encypt(时间戳。ToString(' ss '));返回MD5 encyppt(security key。ToString());}当p回呼a时,Token在a中进行验证,如果验证不成功,则向p站请求统一授权验证.
///摘要///授权枚举////摘要公共枚举AuthCodeEnum { Public=1,Login=2 } ///摘要///授权过滤器////摘要公共类AuthAttribute : ActionFilterAttribute {///summary///权限代码////摘要公共AuthCodeEnum代码{获取设置;} ///摘要///验证权限////summary////param name=' filter context '/param public override void on action executing(action executing context filter context){ var request=filter context .请求;var session=filterContext .会话;//如果存在身份信息if (Common .CurrentUser==null){ if(Code==AuthCodeEnum .public){ return;}字符串reqToken=请求[' Token '];字符串票证=请求【‘票’】;缓存缓存=HttpContext .当前。缓存;//没有获取到代币或者代币验证不通过或者没有取到从P回调的票都进行再次请求p令牌模型令牌模型=缓存获取(常量ThErper ).TOKEN_KEY)==null?null:(令牌模型)缓存获取(常量ThErper ).TOKEN _ KEY);如果(字符串IsNullOrEmpty(reqToken)| | token模型==null | | token模型.令牌!=reqToken ||字符串IsNullOrEmpty(票证)){ DateTime时间戳=DateTime .现在;字符串returnUrl=请求Url。绝对的令牌模型=新令牌模型{时间戳=时间戳,令牌=AuthernUtil .CreateToken(时间戳)};//令牌加入缓存中,设计过期时间为20分钟缓存。添加(常量)。令牌密钥,令牌模型,空,日期时间。现在。添加分钟(20),缓存NoSlidingExpiration,CacheItemPriority .默认值,null);filterContext .结果=新内容结果{内容=GetAuthernScript(AuthernUtil .GetAutherUrl(令牌模型。令牌、时间戳)、返回URl)};返回;}登录服务服务=新登录服务();var userinfo=service .GetUserInfo(票证);会话[常量theper .用户_会话_密钥]=用户信息;//验证通过,缓存中去掉令牌,保证每个代币只能使用一次缓存。移除(常量)。TOKEN _ KEY);} } ///摘要///生成跳转脚本////summary///param name=' authernUrl '统一授权地址/param ///param name='returnUrl '回调地址/param /返回/返回私有字符串GetAuthernScript(string authernUrl,string return URL){ StringBuilder sbScript=new StringBuilder();sbScript .追加('脚本类型=' text/JavaScript ' ');sbScript .AppendFormat('窗口。位置。href=“{ 0 }”返回URl=“encodeURIComponent(“{ 1 }”);”,authernUrl,返回URL);sbScript .追加('/script ');返回sbScript .ToString();} }代码说明:这里为了方便设置代币的过期时间,所以使用躲藏来存取令牌,设定代币的失效时间为两分钟,当验证成功则从躲藏中移除令牌。
调取过滤器
[授权(代码=AuthCodeEnum .登录)])公共操作结果索引(){返回视图();}P站主要逻辑
P站收到授权请求,P站首先通过Coookie来判断是否登陆,未登录则跳转至登陆页面进行登陆操作。
///摘要///授权登陆验证////summary////returns/returns[httpset]公共操作结果PassportVertify(){ var cookie=Request .饼干[常数ThErper .USER _ COOKIE _ KEY];if (cookie==null ||string .IsNullOrEmpty(cookie .ToString())){ returnredirectto action(' log in ',new { return URL=Request[' return URL '],Token=Request[' Token ']});}字符串userinfo=cookie .ToString();var success=passportservice .验证验证(请求['令牌'],转换今日时间(请求['时间戳']);if(!成功){返回RedirectToAction('Login ',new { return URL=Request[' return URL '],Token=Request[' Token ']});}返回重定向(passportservice .GetReturnUrl(userinfo,Request['Token'],Request[' ReturnUrl ']);}已登陆则验证代币
///摘要///验证令牌////summary////param name=' token '令牌/param ///param名称='时间戳'时间戳/param /返回/返回公共bool AuthernVertify(字符串标记,日期时间时间戳){返回AuthernUtil .CreateToken(时间戳)=token}测试说明
1、修改宿主
127 .0 .0 .1 www.passport.com
127 .0 .0 .1 www.a.com
127 .0 .0 .1 www.b.com
2、部署(同移民检查员移民检查)
P www.passport.com:801
A www.a.com:802
B www.b.com:803
3、测试账号和webconfig
添加密钥='PassportCenterUrl '值=' http://www。护照。com :801/
用户名:管理员密码:123
演示
下载地址:源码下载地址
原文链接:http://www .cn博客。com/mines nil-forfaith/p/6062943。超文本标记语言
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
版权声明:的设计与实践 网络单点登录是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。

















