Asp.net mvc 3 MVC授权问题/重复登录请求
我已经建立了一个授权模式来处理对子域站点的访问,并确保用户只能访问与站点相关的数据 我使用“标准”codefirst表单授权,其中我已将属性SiteId添加到所有方法以及所有表中。(示例如下所示-很抱歉长度过长) 这样,登录到不同子域站点的用户可以在其子域中使用相同的用户名 我还在所有其他表中使用siteID,以确保使用客户数据的授权用户使用的是仅与其子域相关的客户数据 在本地,在dev机器上,它可以正常工作 然而,一旦我将应用程序放到web主机上,每隔几分钟我就会被重定向到登录屏幕。一旦它发生在一个站点上,我就会从我登录的所有其他站点重定向。 (site1.myapp.com、site2.maypp.com等) 所有站点都指向同一个应用程序(site1.myapp.com) 因此,问题是:Asp.net mvc 3 MVC授权问题/重复登录请求,asp.net-mvc-3,authorization,subdomain,multi-tenant,Asp.net Mvc 3,Authorization,Subdomain,Multi Tenant,我已经建立了一个授权模式来处理对子域站点的访问,并确保用户只能访问与站点相关的数据 我使用“标准”codefirst表单授权,其中我已将属性SiteId添加到所有方法以及所有表中。(示例如下所示-很抱歉长度过长) 这样,登录到不同子域站点的用户可以在其子域中使用相同的用户名 我还在所有其他表中使用siteID,以确保使用客户数据的授权用户使用的是仅与其子域相关的客户数据 在本地,在dev机器上,它可以正常工作 然而,一旦我将应用程序放到web主机上,每隔几分钟我就会被重定向到登录屏幕。一旦它发生
1) if anyone has an idea/experience in what may be the cause/solution for this and
2) perhaps suggestion on different (better) implementation method
缓存是否会导致系统如此频繁地请求登录授权
以下是我当前设置的示例:
public class User
{
//Membership required
[Key()]
public virtual Guid UserId { get; set; }
public int SiteID { get; set; }
[Required()]
[MaxLength(20)]
public virtual string Username { get; set; }
[Required()]
[MaxLength(250)]
[DataType(DataType.EmailAddress)]
public virtual string Email { get; set; }
...
成员资格提供程序正在使用的站点ID也是:
public class CodeFirstMembershipProvider : CodeFirstExtendedProvider
{
private string _ApplicationName;
private int siteID = Convert.ToInt16(new AppSettings()["SiteID"]);
...
...
public override string ExtendedValidateUser(string userNameOrEmail, string password)
{
...
...
using (DbContext context = new DbContext())
{
User user = null;
user = context.Users.FirstOrDefault(Usr =>( Usr.Username == userNameOrEmail ) && (Usr.SiteID == siteID));
if (user == null)
{
user = context.Users.FirstOrDefault(Usr => (Usr.Email == userNameOrEmail ) && (Usr.SiteID == siteID));
}
...
...
在每个控制器中,我有:
[Authorize]
public class CustomerController : Controller
{
int siteID = Convert.ToInt16(new AppSettings()["SiteID"]);
...
public ViewResult Index()
{
var data = (from k in context.Customers
from ks in context.CustomerSites
where ((k.CustomerID == ks.CustomerID) && (ks.SiteID == siteID) && (ks.CompleteAccess == true))
select (k)).ToList();
...
...
正在使用AppSettings类缓存SiteID::
/// <summary>
/// This class is used to manage the Cached AppSettings
/// from the Database
/// </summary>
public class AppSettings
{
/// This indexer is used to retrieve AppSettings from Memory (only siteID for now)
public string this[string Name]
{
get
{
//See if we have an AppSettings Cache Item
if (HttpContext.Current.Cache["AppSettings"] == null)
{
int? SiteID = 0;
//Look up the URL and get the Tenant/Site Info
using (DbContext dc =
new DbContext())
{
Site result =
dc.Sites
.Where(a => a.Host ==
HttpContext.Current.Request.Url.
Host.ToLower())
.FirstOrDefault();
if (result != null)
{
SiteID = result.SiteID; }
}
AppSettings.LoadAppSettings(SiteID, FirmaID);
}
Hashtable ht =
(Hashtable)HttpContext.Current.Cache["AppSettings"];
if (ht.ContainsKey(Name))
{
return ht[Name].ToString();
}
else
{
return string.Empty;
}
}
//
///此类用于管理缓存的AppSettings
///从数据库
///
公共类应用程序设置
{
///此索引器用于从内存中检索AppSettings(目前仅限于siteID)
公共字符串此[字符串名称]
{
得到
{
//查看是否有AppSettings缓存项
if(HttpContext.Current.Cache[“AppSettings”]==null)
{
int?SiteID=0;
//查找URL并获取租户/站点信息
使用(DbContext)dc=
新建DbContext())
{
现场结果=
dc.站点
.其中(a=>a.主机==
HttpContext.Current.Request.Url。
Host.ToLower())
.FirstOrDefault();
如果(结果!=null)
{
SiteID=result.SiteID;}
}
AppSettings.LoadAppSettings(SiteID,FirmaID);
}
哈希表ht=
(哈希表)HttpContext.Current.Cache[“AppSettings”];
if(ht.CONTANSKEY(名称))
{
返回ht[Name].ToString();
}
其他的
{
返回字符串。空;
}
}
}
//
///此方法用于从加载应用程序设置
///将数据库存储到内存中
///
公共静态void LoadAppSettings(int?SiteID)
{
Hashtable ht=新的Hashtable();
//现在加载应用程序设置
使用(DbContext)dc=
新建DbContext())
{
ht.添加(“站点ID”,站点ID);
}
//将其添加到缓存中(缓存在3小时后过期)
HttpContext.Current.Cache.Add(“AppSettings”,
ht,null,
System.Web.Caching.Cache.NoAbsoluteExport,
新的时间跨度(3,0,0),
System.Web.Caching.CacheItemPriority.NotRemovable,null);
}
}
Aargh….在我尝试了很多东西之后,它像往常一样变成了一个非常简单的问题/解决方案:
由于此应用程序托管在共享web主机上,我需要在web.config中添加机器密钥。 (这就是为什么我不能在我的开发机器上重现这个错误。) 此处有生成一个的链接:
/// <summary>
/// This Method is used to load the app settings from the
/// database into memory
/// </summary>
public static void LoadAppSettings(int? SiteID)
{
Hashtable ht = new Hashtable();
//Now Load the AppSettings
using (DbContext dc =
new DbContext())
{
ht.Add("SiteID", SiteID);
}
//Add it into Cache (Have the Cache Expire after 3 Hour)
HttpContext.Current.Cache.Add("AppSettings",
ht, null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
new TimeSpan(3, 0, 0),
System.Web.Caching.CacheItemPriority.NotRemovable, null);
}
}