我有2个Web应用程序,它们都与下面提到的相同的主级域共享相同的主级域,因此我可以共享cookie。Web.conifg在两个项目中都有相同的计算机密钥和验证密钥。由于,我想使用身份,而不是表单AuthentIcaiton,因此我在我的任何一个web.config文件中都没有一个节点。我能够从SSO成功创建Auth cookie,并可以在SSO中查看授权页面,但是当我尝试访问MVC项目中的授权视图时,我仍然重定向到SSO登录。
- sso.domain.com -MVC项目
- mvc.domain.com -MVC项目
我在我的SSO和MVC项目中有一个启动.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项目中迄今已有的代码。我在下面调用IdentitySignin函数,以验证用户针对创建cookie的数据库:
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;
}
所以,我找出了单个登录在2个MVC应用程序之间不起作用的原因。
我的SSO MVC应用程序和其他MVC应用程序都使用了OWIN和ASP.NET身份DLL的不同版本。我使用Nuget更新一个项目中的DLL,但没有在另一个项目中进行更新。
我希望这对遇到这个问题的人有帮助。
作为仅供参考,在超过1个应用程序之间共享ASP.NET身份身份验证,请确保您在>每个应用程序中都有以下内容:
- web.config文件中的同一机器键和验证键
- OWIN和ASP.NET身份DLL的相同版本
- 在启动中相同的cookie名称和cookie域。cs
- 两个应用都需要在同一域中共享auth cookie
很可能,您没有设置共享机器密钥。Auth Cookie已加密,除非两个站点共享同一机器密钥,否则一个人不能解密另一个加密的内容。将以下内容添加到两个项目的web.config:
<sytem.web>
...
<machineKey validation="HMACSHA256" validationKey="[validationKey]" decryptionKey="[decryptionKey]" compatibilityMode="Framework45" />
要在IIS中生成密钥,请单击左窗格中的服务器,然后单击机器钥匙控制面板项目。选择您的验证方法(上面,我使用了HMACSHA256)。我不建议使用SHA1的默认值,因为这很容易破裂。然后,在右侧的"操作"面板上,单击"生成密钥"。将两个文本框值复制到此配置元素的适当属性,并确保所有需要共享auth cookie的项目相同。