首页 > 代码库 > MVC SSO登陆 的麻烦事~

MVC SSO登陆 的麻烦事~

前段时间用MVC + Redis 做session做了个简单的单点Web站。真是日了狗的问题多。

今天正好睡不着,做个备忘笔记>_<

实现方法很简单,无非就是从重载个Controller或 做一个ActionFilterAttribute就可以达到目的。

下面贴一个Controller的代码实现,ActionFilterAttribute实现方式类似

这里我为了图方便用了servicestack.redis 虽然最新的免费版本 有很大的性能限制(真坑爹)。

两个Controller 类,Base用于在Action执行前填充的Account信息,一个要求必须登陆,否则调到SSO

    
/// <summary>
/// 为所有Action填充Account用户信息
/// </summary>

  public class BaseAccountController : Controller { protected RedisHelper.RedisHelper redisHelper { get; private set; } protected readonly static String TokenKeyCookie = "QTMAccountTokenCookie"; public BaseAccountController() { redisHelper = new RedisHelper.RedisHelper(); } ~BaseAccountController() { if (redisHelper != null) { redisHelper.Dispose(); } } protected override void OnActionExecuting(ActionExecutingContext filterContext) { var cookie = filterContext.HttpContext.Request.Cookies[TokenKeyCookie]; String token = filterContext.HttpContext.Request.QueryString["Token"]; if (cookie != null) { token = cookie.Value; var accountIndex = redisHelper.Get<AccountIndex>(token); ViewBag.CurrentAccount = accountIndex; } else if (!String.IsNullOrWhiteSpace(token)) { var accountIndex = CreateTokenCookie(token); ViewBag.CurrentAccount = accountIndex; } } /// <summary> /// 创建Token令牌的本地Cookie /// </summary> /// <param name="Token">Token令牌</param> /// <returns></returns> protected AccountIndex CreateTokenCookie(string Token) { var accountIndex = redisHelper.Get<AccountIndex>(Token); //判断是否 为有效的Token令牌 if (accountIndex == null) { return null; } //生产Token令牌的Cookie var token_cookie = new HttpCookie(TokenKeyCookie, Token) { HttpOnly = true, Secure = FormsAuthentication.RequireSSL, Path = "/", Expires = DateTime.Now.AddYears(10) }; HttpContext.Response.Cookies.Add(token_cookie); return accountIndex; }

    /// <summary>    /// 控制器的 所有Action必须 持有 有效的 Account Token令牌。    /// </summary>    public class AccountAuthenController : BaseAccountController    {        public AccountAuthenController()            : base()        {        }        ~AccountAuthenController()        {            if (redisHelper != null)            {                redisHelper.Dispose();            }        }        protected override void OnActionExecuting(ActionExecutingContext filterContext)        {            String token = filterContext.HttpContext.Request.QueryString["Token"];            var cookie = filterContext.HttpContext.Request.Cookies[TokenKeyCookie];            if (cookie == null)            {                if (!String.IsNullOrWhiteSpace(token))                {                    //当有返回新的Token令牌时,创建一个新的Token本地Cookie                    var accountIndex = CreateTokenCookie(token);                    if (accountIndex == null)                    {                        filterContext.HttpContext.Response.Redirect(String.Format(ActionUri.Login, filterContext.HttpContext.Request.Url.AbsoluteUri));                    }                }                else                {                    filterContext.HttpContext.Response.Redirect(String.Format(ActionUri.Login, filterContext.HttpContext.Request.Url.AbsoluteUri));                }            }            else            {                token = cookie.Value;                var accountIndex = redisHelper.Get<AccountIndex>(token);                if (accountIndex == null)                {   //无效的Token Cookie                    filterContext.HttpContext.Response.Cookies[TokenKeyCookie].Expires = DateTime.Now.AddYears(-1);                    filterContext.HttpContext.Response.Redirect(String.Format(ActionUri.Login, filterContext.HttpContext.Request.Url.AbsoluteUri));                }            }            base.OnActionExecuting(filterContext);        }        #region Private Method        #endregion    }

 

MVC SSO登陆 的麻烦事~