优化SSO登录

This commit is contained in:
yubaolee 2016-12-27 11:25:51 +08:00
parent a3bdcf83ec
commit ccf1269eca
19 changed files with 108 additions and 240 deletions

View File

@ -0,0 +1,44 @@
// ***********************************************************************
// Assembly : Helper
// Author : yubaolee
// Created : 12-16-2016
//
// Last Modified By : yubaolee
// Last Modified On : 12-21-2016
// 使用微软默认带超时的Cache
// File: CacheContext.cs
// ***********************************************************************
using System;
using System.Web;
namespace Infrastructure.Cache
{
public class CacheContext : ICacheContext
{
private readonly System.Web.Caching.Cache _objCache = HttpRuntime.Cache;
public override T Get<T>(string key)
{
System.Web.Caching.Cache objCache = HttpRuntime.Cache;
return (T) objCache[key];
}
public override bool Set<T>(string key, T t, DateTime expire)
{
var obj = Get<T>(key);
if (obj != null)
{
Remove(key);
}
_objCache.Insert(key, t, null, expire, System.Web.Caching.Cache.NoSlidingExpiration);
return true;
}
public override bool Remove(string key)
{
_objCache.Remove(key);
return true;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
namespace Helper.Cache
{
[Serializable]
public class CacheObj<T>
{
public string key { get; set; }
public T Obj { get; set; }
public DateTime InvalidTime { get; set; }
public DateTime CreateTime { get; set; }
}
}

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Globalization; using System.Globalization;
namespace Helper.Cache namespace Infrastructure.Cache
{ {
/// <summary> /// <summary>
/// 缓存工厂 /// 缓存工厂

View File

@ -10,40 +10,29 @@
// *********************************************************************** // ***********************************************************************
using System;
using Enyim.Caching; using Enyim.Caching;
using Enyim.Caching.Memcached; using Enyim.Caching.Memcached;
namespace Helper.Cache namespace Infrastructure.Cache
{ {
public sealed class EnyimMemcachedContext : ICacheContext public sealed class EnyimMemcachedContext : ICacheContext
{ {
private readonly MemcachedClient _memcachedClient = new MemcachedClient("memcached"); private static readonly MemcachedClient _memcachedClient = new MemcachedClient();
public override void Init()
{
}
public override T Get<T>(string key) public override T Get<T>(string key)
{ {
return _memcachedClient.Get<T>(key); return _memcachedClient.Get<T>(key);
} }
public override bool Set<T>(string key, T t) public override bool Set<T>(string key, T t, DateTime expire)
{ {
return _memcachedClient.Store(StoreMode.Set, key, t); return _memcachedClient.Store(StoreMode.Set, key, t, expire);
} }
public override bool Remove(string key) public override bool Remove(string key)
{ {
return _memcachedClient.Remove(key); return _memcachedClient.Remove(key);
} }
public override void Dispose()
{
if (_memcachedClient != null)
{
_memcachedClient.Dispose();
}
}
} }
} }

View File

@ -1,65 +0,0 @@
// ***********************************************************************
// Assembly : Helper
// Author : Administrator
// Created : 09-21-2016
//
// Last Modified By : Administrator
// Last Modified On : 11-09-2016
// Contact :
// File: HttpApplicationContext.cs
// ***********************************************************************
using System;
using System.Web;
namespace Helper.Cache
{
/// <summary>
/// 基于HttpApplication的存储
/// <para>李玉宝新增于2016-11-09 9:30:51</para>
/// </summary>
public sealed class HttpApplicationContext : ICacheContext
{
public override void Init()
{
}
public override T Get<T>(string key)
{
return (T) HttpContext.Current.Application[key];
}
public override bool Set<T>(string key, T t)
{
try
{
HttpContext.Current.Application[key] = t;
return true;
}
catch (Exception)
{
return false;
}
}
public override bool Remove(string key)
{
try
{
HttpContext.Current.Application[key] = null;
return true;
}
catch (Exception)
{
return false;
}
}
public override void Dispose()
{
}
}
}

View File

@ -1,24 +1,19 @@
using System; using System;
namespace Helper.Cache namespace Infrastructure.Cache
{ {
/// <summary> /// <summary>
/// 缓存接口 /// 缓存接口
/// </summary> /// </summary>
public abstract class ICacheContext : IDisposable public abstract class ICacheContext
{ {
/// <summary>
/// 初始化缓存组件
/// </summary>
public abstract void Init();
/// <summary> /// <summary>
/// 获取缓存项 /// 获取缓存项
/// </summary> /// </summary>
/// <typeparam name="T">缓存对象类型</typeparam> /// <typeparam name="T">缓存对象类型</typeparam>
/// <param name="key">键</param> /// <param name="key">键</param>
/// <returns>缓存对象</returns> /// <returns>缓存对象</returns>
public abstract T Get<T>(string key) where T : class; public abstract T Get<T>(string key) ;
/// <summary> /// <summary>
/// 设置缓存项 /// 设置缓存项
@ -27,7 +22,7 @@ namespace Helper.Cache
/// <param name="key">键</param> /// <param name="key">键</param>
/// <param name="t">缓存对象</param> /// <param name="t">缓存对象</param>
/// <returns>true成功,false失败</returns> /// <returns>true成功,false失败</returns>
public abstract bool Set<T>(string key, T t) where T : class; public abstract bool Set<T>(string key, T t, DateTime expire);
/// <summary> /// <summary>
/// 移除一个缓存项 /// 移除一个缓存项
@ -36,9 +31,5 @@ namespace Helper.Cache
/// <returns>true成功,false失败</returns> /// <returns>true成功,false失败</returns>
public abstract bool Remove(string key); public abstract bool Remove(string key);
/// <summary>
/// 释放缓存组件
/// </summary>
public abstract void Dispose();
} }
} }

View File

@ -1,39 +1,34 @@
// *********************************************************************** // ***********************************************************************
// Assembly : OpenAuth.WebApi // Assembly : Helper
// Author : yubaolee // Author : Administrator
// Created : 07-11-2016 // Created : 12-21-2016
// //
// Last Modified By : yubaolee // Last Modified By : Administrator
// Last Modified On : 07-11-2016 // Last Modified On : 12-22-2016
// Contact : // Contact :
// File: CacheObjService.cs // File: ObjCacheProvider.cs
// *********************************************************************** // ***********************************************************************
using System; using System;
namespace Helper.Cache namespace Infrastructure.Cache
{ {
/// <summary> /// <summary>
/// 带超时结构的缓存 /// 缓存工厂实现
/// 这样做是方便换其他的缓存时如memcachedContext只换这一个地方即可
/// </summary> /// </summary>
public class ObjCacheProvider<T> : CacheProvider public class ObjCacheProvider<T> : CacheProvider
{ {
public ObjCacheProvider() public ObjCacheProvider()
{ {
SetCacheInstance(new HttpApplicationContext()); SetCacheInstance(new CacheContext());
} }
public bool Create(string key, T val) public bool Create(string key, T val, DateTime expire)
{ {
var cacheobj = new CacheObj<T>
{
key = key,
InvalidTime = DateTime.Now.AddMinutes(5),
CreateTime = DateTime.Now,
Obj = val
};
//设置缓存 //设置缓存
return CacheContext.Set(key, cacheobj); return CacheContext.Set<T>(key, val, expire);
} }
/// <summary> /// <summary>
@ -43,18 +38,7 @@ namespace Helper.Cache
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
public T GetCache(string key) public T GetCache(string key)
{ {
var cache = CacheContext.Get<CacheObj<T>>(key); return CacheContext.Get<T>(key);
if (cache == null) return default(T);
if (cache.InvalidTime > DateTime.Now)
{
return cache.Obj;
}
//移除无效Session缓存
Remove(key);
return default(T);
} }
public void Remove(string key) public void Remove(string key)

View File

@ -80,10 +80,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AutoMapperExt.cs" /> <Compile Include="AutoMapperExt.cs" />
<Compile Include="Cache\CacheObj.cs" /> <Compile Include="Cache\CacheContext.cs" />
<Compile Include="Cache\CacheProvider.cs" /> <Compile Include="Cache\CacheProvider.cs" />
<Compile Include="Cache\EnyimMemcachedContext.cs" /> <Compile Include="Cache\EnyimMemcachedContext.cs" />
<Compile Include="Cache\HttpApplicationContext.cs" />
<Compile Include="Cache\ICacheContext.cs" /> <Compile Include="Cache\ICacheContext.cs" />
<Compile Include="Cache\ObjCacheProvider.cs" /> <Compile Include="Cache\ObjCacheProvider.cs" />
<Compile Include="CookieHelper.cs" /> <Compile Include="CookieHelper.cs" />

View File

@ -98,7 +98,6 @@
<Compile Include="SSO\LoginResult.cs" /> <Compile Include="SSO\LoginResult.cs" />
<Compile Include="SSO\SSOAuthAttribute.cs" /> <Compile Include="SSO\SSOAuthAttribute.cs" />
<Compile Include="SSO\UserAuthSession.cs" /> <Compile Include="SSO\UserAuthSession.cs" />
<Compile Include="SSO\UserAuthSessionService.cs" />
<Compile Include="CommonApplyApp.cs" /> <Compile Include="CommonApplyApp.cs" />
<Compile Include="StockManagerApp.cs" /> <Compile Include="StockManagerApp.cs" />
<Compile Include="UserManagerApp.cs" /> <Compile Include="UserManagerApp.cs" />

View File

@ -1,6 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using Helper.Cache; using Infrastructure.Cache;
namespace OpenAuth.App.SSO namespace OpenAuth.App.SSO
{ {

View File

@ -150,7 +150,7 @@ namespace OpenAuth.App.SSO
var token = GetToken(); var token = GetToken();
if (String.IsNullOrEmpty(token)) return true; if (String.IsNullOrEmpty(token)) return true;
var requestUri = String.Format("/SSO/Login/Logout?token={0}&requestid={1}", token, ""); var requestUri = String.Format("/SSO/Check/Logout?token={0}&requestid={1}", token, "");
try try
{ {

View File

@ -23,7 +23,7 @@ namespace OpenAuth.App.SSO
token = request.QueryString[Token]; token = request.QueryString[Token];
var cookie = new HttpCookie(Token, token) var cookie = new HttpCookie(Token, token)
{ {
Expires = DateTime.Now.AddDays(1) Expires = DateTime.Now.AddDays(10)
}; };
filterContext.HttpContext.Response.Cookies.Add(cookie); filterContext.HttpContext.Response.Cookies.Add(cookie);
} }

View File

@ -2,6 +2,7 @@ using System;
using System.Web; using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
using Infrastructure; using Infrastructure;
using Infrastructure.Cache;
using OpenAuth.Domain; using OpenAuth.Domain;
@ -55,14 +56,13 @@ namespace OpenAuth.App.SSO
{ {
UserName = model.UserName, UserName = model.UserName,
Token = Guid.NewGuid().ToString().GetHashCode().ToString("x"), Token = Guid.NewGuid().ToString().GetHashCode().ToString("x"),
InvalidTime = DateTime.Now.AddDays(1),
AppKey = model.AppKey, AppKey = model.AppKey,
CreateTime = DateTime.Now, CreateTime = DateTime.Now,
IpAddress = HttpContext.Current.Request.UserHostAddress IpAddress = HttpContext.Current.Request.UserHostAddress
}; };
//´´½¨Session //´´½¨Session
new UserAuthSessionService().Create(currentSession); new ObjCacheProvider<UserAuthSession>().Create(currentSession.Token, currentSession, DateTime.Now.AddDays(10));
result.Success = true; result.Success = true;
result.ReturnUrl = appInfo.ReturnUrl; result.ReturnUrl = appInfo.ReturnUrl;

View File

@ -37,7 +37,7 @@ namespace OpenAuth.App.SSO
token = request.QueryString[Token]; token = request.QueryString[Token];
var cookie = new HttpCookie(Token, token) var cookie = new HttpCookie(Token, token)
{ {
Expires = DateTime.Now.AddDays(1) Expires = DateTime.Now.AddDays(10)
}; };
filterContext.HttpContext.Response.Cookies.Add(cookie); filterContext.HttpContext.Response.Cookies.Add(cookie);
} }

View File

@ -13,8 +13,6 @@ namespace OpenAuth.App.SSO
public string IpAddress { get; set; } public string IpAddress { get; set; }
public DateTime InvalidTime { get; set; }
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
} }
} }

View File

@ -1,70 +0,0 @@
// ***********************************************************************
// Assembly : OpenAuth.WebApi
// Author : yubaolee
// Created : 07-11-2016
//
// Last Modified By : yubaolee
// Last Modified On : 07-11-2016
// Contact :
// File: UserAuthSessionService.cs
// ***********************************************************************
using System;
using Helper.Cache;
using Infrastructure;
namespace OpenAuth.App.SSO
{
/// <summary>
/// 用户登录状态存储服务
/// <para>测试环境用的是基于http application的SessionContext</para>
/// <para>正式环境可以使用基于memcached的EnyimMemcachedContext</para>
/// </summary>
public class UserAuthSessionService : CacheProvider
{
public UserAuthSessionService()
{
SetCacheInstance(new HttpApplicationContext());
}
public bool Create(UserAuthSession model)
{
//设置缓存
return CacheContext.Set(model.Token, model);
}
public UserAuthSession Get(string token)
{
var sessionCacheItem = CacheContext.Get<UserAuthSession>(token);
return sessionCacheItem;
}
public bool GetCache(string token)
{
var cache = Get(token);
if (cache == null) return false;
LogHelper.Log(token
+ "用户:" + cache.UserName
+ "登陆有效时间:" + cache.InvalidTime);
if (cache.InvalidTime > DateTime.Now)
{
//延长
cache.InvalidTime = DateTime.Now.AddDays(1);
//设置缓存
CacheContext.Set(cache.Token, cache);
return true;
}
//移除无效Session缓存
Remove(token);
return false;
}
public void Remove(string token)
{
CacheContext.Remove(token);
}
}
}

View File

@ -9,8 +9,10 @@
// File: CheckController.cs // File: CheckController.cs
// *********************************************************************** // ***********************************************************************
using System;
using System.Web.Mvc; using System.Web.Mvc;
using Infrastructure; using Infrastructure;
using Infrastructure.Cache;
using OpenAuth.App; using OpenAuth.App;
using OpenAuth.App.SSO; using OpenAuth.App.SSO;
@ -24,6 +26,7 @@ namespace OpenAuth.WebApi.Areas.SSO.Controllers
public class CheckController : Controller public class CheckController : Controller
{ {
private AuthorizeApp _app; private AuthorizeApp _app;
private ObjCacheProvider<UserAuthSession> _objCacheProvider = new ObjCacheProvider<UserAuthSession>();
public CheckController() public CheckController()
{ {
_app = AutofacExt.GetFromFac<AuthorizeApp>(); _app = AutofacExt.GetFromFac<AuthorizeApp>();
@ -31,7 +34,7 @@ namespace OpenAuth.WebApi.Areas.SSO.Controllers
public bool GetStatus(string token = "", string requestid = "") public bool GetStatus(string token = "", string requestid = "")
{ {
if (new UserAuthSessionService().GetCache(token)) if (_objCacheProvider.GetCache(token) != null)
{ {
return true; return true;
} }
@ -52,7 +55,7 @@ namespace OpenAuth.WebApi.Areas.SSO.Controllers
public string GetUserName(string token, string requestid = "") public string GetUserName(string token, string requestid = "")
{ {
var user = new UserAuthSessionService().Get(token); var user = _objCacheProvider.GetCache(token);
if (user != null) if (user != null)
{ {
return user.UserName; return user.UserName;
@ -66,5 +69,19 @@ namespace OpenAuth.WebApi.Areas.SSO.Controllers
{ {
return JsonHelper.Instance.Serialize(SSOAuthUtil.Parse(request)); return JsonHelper.Instance.Serialize(SSOAuthUtil.Parse(request));
} }
[HttpPost]
public bool Logout(string token, string requestid)
{
try
{
_objCacheProvider.Remove(token);
return true;
}
catch (Exception)
{
return false;
}
}
} }
} }

View File

@ -51,21 +51,5 @@ namespace OpenAuth.WebApi.Areas.SSO.Controllers
TempData[AppInfo] = _appInfoService.Get(model.AppKey); TempData[AppInfo] = _appInfoService.Get(model.AppKey);
return View(model); return View(model);
} }
[HttpPost]
public bool Logout(string token, string requestid)
{
try
{
new UserAuthSessionService().Remove(token);
return true;
}
catch (Exception)
{
return false;
}
}
} }
} }

View File

@ -8,11 +8,25 @@
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" /> <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/>
</sectionGroup>
</configSections> </configSections>
<connectionStrings> <connectionStrings>
<add name="OpenAuthDBContext" connectionString="Data Source=.;Initial Catalog=OpenAuthDB;Persist Security Info=True;User ID=sa;Password=000000;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /> <add name="OpenAuthDBContext" connectionString="Data Source=.;Initial Catalog=OpenAuthDB;Persist Security Info=True;User ID=sa;Password=000000;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
<!--<add name="OpenAuthDBContext" connectionString="server=127.0.0.1;user id=root;persistsecurityinfo=True;database=openauth;password=123456" providerName="MySql.Data.MySqlClient" />--> <!--<add name="OpenAuthDBContext" connectionString="server=127.0.0.1;user id=root;persistsecurityinfo=True;database=openauth;password=123456" providerName="MySql.Data.MySqlClient" />-->
</connectionStrings> </connectionStrings>
<enyim.com>
<memcached protocol="Binary">
<servers>
<add address="127.0.0.1" port="11211"/>
</servers>
</memcached>
</enyim.com>
<appSettings> <appSettings>
<add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" /> <add key="webpages:Enabled" value="false" />