0

我已经设置了一个授权模式来处理对子域站点的访问,并确保用户只能访问与站点相关的数据。

我使用“标准”codefirst 表单授权,其中我已将属性 SiteId 添加到所有方法以及所有表中。(示例如下所示 - 抱歉它的长度)

这样,登录不同子域站点的用户可以在其子域中使用相同的用户名。

我还在所有其他表中使用 siteID 以确保授权用户使用,例如,客户数据正在使用仅与其子域相关的客户数据。

在本地,在开发机器上,它可以正常工作。

但是,一旦我将应用程序放到网络主机上,我每隔几分钟就会被重定向到登录屏幕。一旦它发生在其中一个站点上,我就会从我登录的所有其他站点重定向。(site1.myapp.com,site2.maypp.com,....)所有站点都指向同一个应用程序( site1.myapp.com)

所以问题是:

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; }
    ...

会员提供者也在使用 siteID:

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;
     }
  }

}

/// <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);
     }
  }
4

1 回答 1

1

啊……
经过我尝试了很多事情,结果证明它通常是非常简单的问题/解决方案:

由于此应用程序托管在共享 Web 主机上,因此我需要在 web.config中添加机器密钥。(这就是为什么我无法在我的开发机器上重现此错误的原因。)

生成链接在这里:机器密钥生成器

于 2012-05-16T08:17:04.400 回答