zoukankan      html  css  js  c++  java
  • MVC SSO登陆 的麻烦事~

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

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

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

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

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

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

    PS:可做小修改,例如带Token时二次重定向刷新页面或是将Token存入Cache。

        
    /// <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
        }
  • 相关阅读:
    Chapter 2 Sockets and Patterns【选译,哈哈】 Part 2 Messags Partterns
    WPF动态更改Image控件图片路径
    Chapter 2 Sockets and Patterns【选译,哈哈】 Part 1
    Chapter 2 Sockets and Patterns【选译,哈哈】 Part 4 Handling Errors and ETERM
    Chapter 2 Sockets and Patterns【选译,哈哈】 Part 3 Messags Partterns
    Visual Studio 2008 测试项目无法正常显示解决办法
    Ext.NET控件介绍—Form控件
    ThoughtWorks(中国)程序员读书雷达
    Ext.net 中日期格式的计算
    Sql 分割 键值对字符串 得到某值对应的名称
  • 原文地址:https://www.cnblogs.com/linqing/p/5922433.html
Copyright © 2011-2022 走看看