Lind.DDD.SSO单点登陆组件的使用(原创)
一般sso的说明
在Lind.DDD框架里,有对单点登陆的集成,原理就是各个网站去sso网站统一登陆授权,之后在sso网站将登陆的token进行存储,存储方式随你(cache,redis,mongodb,file),之后业务平台在访问资源时,如果这些资源需要用户登陆才能访问,就会去sso网站取token,再根据token去凭证,然后将cookies(由sso域名+token值组成)存储到自己浏览器的cookies里,同时在自己的业务平台也存储的登陆状态,当退出后,将sso上存储的信息清空,其它业务平台登陆状态保持不变,当然我们的token和session都有自己的超时时间,这个可以根据需要去设置。对于业务平台只需要添加统一的Filter即可,在业务平台的登陆功能上,直接调用框架里的登出功能,而sso也只需要实现登陆页面,并调用框架的登陆功能!
大叔sso里各模块的关系
大叔sso的工作流程
对于代码,我们在客户端开放一个Filter,用来作授权,它与sso服务器会有几次通讯(几次握手)分别是:
-》从sso取一个token
-》将token存储到本机cookies上
-》通过token去服务器取凭证Credence
-》将Credence存储到业务平台的session上
-》用户在sso授权成功,完成了统一登陆,用户访问这个业务平台,由于凭证存储在session上,所以,本用户处理登陆状态
SSOActionFilter核心代码展示
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) { var Request = filterContext.HttpContext.Request; var Response = filterContext.HttpContext.Response; var Session = filterContext.HttpContext.Session; Session.Timeout = 30; //令牌存储在第三方Session,退出只退自己平台的账号 if (Session[TOKEN_KEY] != null) { //分站凭证存在 //恭喜,分站凭证存在,您被授权访问该页面! Lind.DDD.Logger.LoggerFactory.Instance.Logger_Debug("恭喜,分站凭证存在,您被授权访问该页面!"); } else { //令牌验证结果 if (Request.QueryString[TOKEN_KEY] != null) { if (Request.QueryString[TOKEN_KEY] != "$Token$") { //持有令牌 string tokenValue = Request.QueryString[TOKEN_KEY]; //调用WebService获取主站凭证[3] var o = new WebClient().DownloadString(getCredenceUri + tokenValue); if (!string.IsNullOrWhiteSpace(o)) { //令牌正确[5,结束] Session[TOKEN_KEY] = o; //序列化用户信息 var obj = o.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries); Lind.DDD.Authorization.CurrentUser.Serialize(obj[0], obj[1]); //恭喜,令牌存在,您被授权访问该页面! Lind.DDD.Logger.LoggerFactory.Instance.Logger_Debug("恭喜,令牌存在,您被授权访问该页面!"); } else { //令牌错误[4] filterContext.Result = new RedirectResult(this.replaceToken()); } } else { //未持有令牌[2],获取令牌 filterContext.Result = new RedirectResult(this.replaceToken()); } } //没能领取令牌,去主站领取[1]$Token$ else { filterContext.Result = new RedirectResult(this.getTokenURL()); } } base.OnActionExecuting(filterContext); }
对于sso来说,只需要实现登陆方法即可,代码非常简洁!
if (isPass) { return SSOManager.LoginSSO("1","zzl",form["BackUrl"]); }
而对于业务平台来说,你完全可以添加一个全局过滤器,或者在需要的控制器上添加SSOActionFilter特性即可,代码依然十分简洁!
[SSOActionFilter] public ActionResult Index() { return View(); }
业务平台自己控制登出方法,当然也是调用框架里封装的方法!
public ActionResult Logout() { SSOManager.ExitSSO(); return RedirectToAction("Index"); }
当前,对于sso这个功能来说,复杂的代码已经封装在了Lind.DDD.SSO模块,我们平台在用于不需要去关注它......
感谢各位对本文章的支持,希望对各位所有帮助!