MVC SSO登陆 的麻烦事~

时间:2023-03-09 18:09:24
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()
}; 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(-);
filterContext.HttpContext.Response.Redirect(String.Format(ActionUri.Login, filterContext.HttpContext.Request.Url.AbsoluteUri));
}
} base.OnActionExecuting(filterContext);
} #region Private Method #endregion
}