サブドメインサイトへのアクセスを処理し、ユーザーがサイト関連のデータのみにアクセスできるようにするための承認スキーマを設定しました。
すべてのメソッドとすべてのテーブルにプロパティSiteIdを追加した、「標準」のコードファーストフォーム認証を使用します。(例を以下に示します-長さについては申し訳ありません)
このようにして、異なるサブドメインサイトにログインするユーザーは、サブドメインで同じユーザー名を使用できます。
また、他のすべてのテーブルでsiteIDを使用して、たとえば、顧客データを操作する許可されたユーザーが、サブドメインのみに関連する顧客データを操作していることを確認します。
ローカルでは、開発マシンでは問題なく動作します。
ただし、アプリをウェブホストに配置すると、数分ごとにログイン画面にリダイレクトされます。そして、ログインしている他のすべてのサイトからリダイレクトされるサイトの1つで発生すると、(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();
...
...
SiteIDは、AppSettingsクラスを使用してキャッシュされています::
/// <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);
}
}