マルチテナントな Web サービスを作っていて、
どのテナントかの判断を現在ログインしているユーザーが持っているテナント ID で判断している。
そのため、HttpContext.User.Identity.GetUserId()
で取得したユーザー ID を使って、
データベースからユーザーを取得してテナント ID を取り出していた。
でも最近、テナント ID をカスタムクレームに追加すればいいことに気付いた。
public static class CustomClaimTypes
{
public const string TenantId = "http://example.org/claims/tenantid";
}
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim(CustomClaimTypes.TenantId, this.TenantId.ToString()));
return userIdentity;
}
public int TenantId { get; set; }
}
public static class IdentityExtensions
{
public static int? GetTenantId(this IIdentity identity)
{
var claimsIdentity = identity as ClaimsIdentity;
if (claimsIdentity != null)
{
var claim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == CustomClaimTypes.TenantId);
if (claim != null)
{
int tenantId;
if (int.TryParse(claim.Value, out tenantId))
{
return tenantId;
}
}
}
return null;
}
}
コントローラーからは HttpContext からたどって取得できる。
this.HttpContext.User.Identity.GetTenantId();
テナントごとに違うサブドメインにできたら、サブドメインでテナントを判別できて一番いいんだけどね。
大人の事情でそれはやらないことになったから、仕方ない。