下記のように両方が同じメインレベルドメインを共有する2つのWebアプリケーションがあるので、Cookieを共有できます。両方のプロジェクトのWeb.conifgには、同じマシンキーと検証キーがあります。 Identityを使用したいので[〜#〜] not [〜#〜]フォームの認証を行うため、どちらのweb.configファイルにもノードがありません。 SSOから認証Cookieを正常に作成でき、SSOで承認されたページを表示できますが、MVCプロジェクトで承認されたビューにアクセスしようとすると、SSOログインにリダイレクトされます。
SSOおよびMVCプロジェクトに次のようなstartup.csファイルがあります:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
// For more information on configuring authentication, please visit http://go.Microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
ExpireTimeSpan = TimeSpan.FromMinutes(3),
LoginPath = new PathString("/Login"),
CookieName = "MyCookieName",
CookieDomain = ".domain.com"
});
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
以下は、AccountController.csの下のSSOプロジェクトでこれまでに使用したコードです。 Cookieを作成するデータベースに対してユーザーを検証する際に、以下のIdentitySignin関数を呼び出します。
private void IdentitySignin(string userId, string name, string providerKey = null, bool isPersistent = false)
{
var claims = new List<Claim>();
// create *required* claims
claims.Add(new Claim(ClaimTypes.NameIdentifier, userId));
claims.Add(new Claim(ClaimTypes.Name, name));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
//get the expiry minutes from config or use the default value of 30 minutes
double expiryMinutes;
expiryMinutes = double.TryParse(ConfigurationManager.AppSettings["AuthCookieExpiryMinutes"], out expiryMinutes) ? expiryMinutes : 30;
// add to user here!
AuthenticationManager.SignIn(new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = isPersistent,
ExpiresUtc = DateTime.UtcNow.AddMinutes(expiryMinutes),
IssuedUtc = DateTime.UtcNow
}, identity);
}
private void IdentitySignout()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);
}
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private async Task<string> GetVerifiedUserIdAsync()
{
var result = await AuthenticationManager.AuthenticateAsync(
DefaultAuthenticationTypes.ApplicationCookie);
if (result != null && result.Identity != null
&& !String.IsNullOrEmpty(result.Identity.GetUserId()))
{
return result.Identity.GetUserId();
}
return null;
}
ほとんどの場合、共有マシンキーを設定していません。認証Cookieは暗号化されており、両方のサイトが同じマシンキーを共有しない限り、一方が他方が暗号化したものを復号化することはできません。両方のプロジェクトのWeb.configに以下を追加します。
<sytem.web>
...
<machineKey validation="HMACSHA256" validationKey="[validationKey]" decryptionKey="[decryptionKey]" compatibilityMode="Framework45" />
キーを生成するには、IISで、左側のウィンドウのサーバーをクリックしてから、[マシンキー]コントロールパネルの項目をクリックします。検証方法を選択します(上記では、HMACSHA256を使用しました)。デフォルトのSHA1を使用することはお勧めしません。これは、途方もなく簡単に解読できるためです。次に、右側の[アクション]パネルで、[キーの生成]をクリックします。 2つのテキストボックスの値をこの構成要素の適切な属性にコピーし、認証Cookieを共有する必要があるすべてのプロジェクトで同じであることを確認します。
そこで、2つのMVCアプリケーションが同じマシンと検証キーを共有しているにもかかわらず、シングルサインオンが機能しなかった理由を理解しました。
私のSSOMVCアプリケーションと他のMVCアプリケーションは、どちらも異なるバージョンのOWINおよびASP.NET IdentityDLLを使用していました。 Nugetを使用して1つのプロジェクトのDLLを更新しましたが、他のプロジェクトでは更新を行いませんでした。
これがこの問題に遭遇した人の助けになることを願っています。
参考までに、複数のアプリケーション間でASP.NET ID認証を共有するには、以下の項目があることを確認してください各APP: