IIS中使用OWIN的MVC父/子站点未传递标识



我需要在IIS中将一个站点嵌套在另一个站点下,这样用户就可以在两者之间来回切换,而无需同时登录。我以前在MVC站点中成功地做到了这一点,删除了子站点的大部分web.config,使其继承父站点的web.config,并在父站点中手动设置machinekey。

在父母那里,我手动设置了机器钥匙,并确认孩子正在取钥匙。

我已经用个人用户帐户(Identity)测试了两个MVC 5 web应用程序。我将第二个应用程序设置为主应用程序下的虚拟应用程序,使用相同的应用程序池。现有的MVC应用程序运行良好。我登录到家长,导航到孩子,它就会获取身份。我可以核实,因为上面写着"欢迎"bdamore@xxxxxx.com'在父站点和子站点中。

但股票应用程序使用股票登录/ApplicationUserManager/ApplicationSignInManager方法,而我们的母应用程序有很多定制的OWIN。

股票MVC网站的登录方法使用:"SignInManager.PasswordSignInAsync(…)">

我们的母网站正在使用:"HttpContext.GetOwinContext().Authentication.SignIn(…)">

父站点仍然在_loginPartial.chtml中使用:"@User.Identity.GetUserName()">,就像大多数库存MVC5子站点一样,但子站点NEVER会像库存MVC5父/子站点一样从父站点获取Identity。User或任何用户声明。

以下是一些登录信息:

var hash = _cryptographyService.HashPassword(model.Password);
var token = _profileService.Login(model.Email, hash);
if (token != null)
{
var userData = SerializeCustomUser(token);
var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaims(new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier,model.Email),
new Claim(ClaimTypes.Name,model.Email),
new Claim("UserId", token.UserId.ToString()),
new Claim("RoleId", token.Role.ToString()),
new Claim("SchoolId", token.SchoolId.ToString()),
new Claim("CampusId", token.CampusId.ToString())
});
if (model.RememberMe)
{
Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(30);
}
else
{
Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(-1);
}
Response.Cookies["UserName"].Value = model.Email.Trim();
HttpContext.GetOwinContext().Authentication.SignIn(identity);
....

_ProfileService.Login进入数据库并验证信用

这是Startup.Auth.cs:

public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
CookieName="VerityAuthSession",
Provider = new CookieAuthenticationProvider {
OnValidateIdentity = context =>
{
var url = System.Web.HttpContext.Current?.Request.Url.ToString().ToLower();
if (url?.IndexOf("signalr") != -1 || url?.IndexOf("TwilioInfo/GetInboundCallDetails".ToLower()) != -1 || url?.IndexOf("CreateLogOffEvent".ToLower()) !=-1)
{
if(url?.IndexOf("signalr") != -1)
{
var cookie = new System.Web.HttpCookie("tmpsession", context?.Identity?.Claims?.FirstOrDefault(x => x.Type == "UserId")?.Value);
cookie.Expires = DateTime.Now.AddSeconds(10);
System.Web.HttpContext.Current?.Response.Cookies.Add(cookie);
}
context.RejectIdentity();
return Task.FromResult<int>(0);
}
DateTimeOffset now = DateTimeOffset.UtcNow;
context.OwinContext.Request.Set<double>("time.Remaining",
context.Properties.ExpiresUtc.Value.Subtract(now).TotalSeconds);
System.Web.HttpContext.Current?.Response.Cookies.Add(new System.Web.HttpCookie("lastaccess", DateTime.UtcNow.ToString("MM.dd.yyyy.HH.mm.ss")));
return Task.FromResult<object>(null);
},
OnException = context => {},
OnResponseSignIn = context =>
{
context.Properties.AllowRefresh = true;
context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings[EnvironmentConsts.SessiontTimeout] ?? "45"));
}
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
// Enables the application to remember the second login verification factor such as phone or email.
// Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
// This is similar to the RememberMe option when you log in.
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
var signalRConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings[EnvironmentConsts.SignaRDbConnectionName].ConnectionString;
GlobalHost.DependencyResolver.UseSqlServer(signalRConnectionString); //for using SignalR with loadbalancer we need this configuration
app.MapSignalR();
}

当我们的网站ajax转到twillio时,启动时需要处理一些代码,这样就不会像导航一样扩展他们的会话

我找到了答案。
  1. 我需要复制整个自定义的app.UseCookieAuthentication(...部分写入StartupAuth.cs文件。父级为cookie提供了一个"Name"属性,显然,它在两个应用程序中都需要相同的名称。

  2. 以下内容需要在我们的自定义设置的OnApplicationStarted()方法中:AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

我们的架构师通过让我们的global.asax.cs从App_Startup文件夹中的一个名为"ParentApplication.cs"的文件继承来为Ninject设置这一点。在那里,ParentApplication.chs文件继承自NinjectHttpApplication.

在这个文件中有一个方法:

protected override void OnApplicationStarted()

希望这能帮助其他人。

最新更新