简体   繁体   English

IIS中使用OWIN的MVC父/子站点未传递身份

[英]MVC parent/child sites in IIS using OWIN is not passing identity

I have a requirement to nest one site under another in IIS so users can go back and forth between the two without logging into both. 我需要将一个站点嵌套在IIS中的另一个站点之下,以便用户可以在两个站点之间来回切换而无需登录到两个站点。 I have done this previously with MVC sites with success by removing most of the child's web.config so it inherits the parent web.config and setting a machinekey manually in the parent config. 之前,我通过删除子级的大部分web.config使其成功地与MVC站点一起完成,因此它继承了父级web.config并在父级配置中手动设置了计算机密钥。

In the parent I set the machine key manually and verified that the child is picking it up. 在父母中,我手动设置机器密钥,并验证孩子正在拿起它。

I have tested two MVC 5 web apps with individual user accounts (Identity). 我已经使用个人用户帐户(身份)测试了两个MVC 5 Web应用程序。 I setup the second app as a virtual application under the main app, using the same app pool. 我使用相同的应用程序池将第二个应用程序设置为主应用程序下的虚拟应用程序。 The stock MVC apps work fine. 股票的MVC应用程序可以正常工作。 I log into the parent, navigate to the child and it picks up the identity. 我登录到父级,导航到该子级,然后它识别了身份。 I can verify because it says 'welcome bdamore@xxxxxx.com' in both parent and child sites. 我可以验证,因为在父站点和子站点中都显示“ welcome bdamore@xxxxxx.com”。

But the stock ones are using the stock login/ApplicationUserManager/ApplicationSignInManager methodology, whereas our parent app has a lot of customized OWIN. 但是股票交易者使用的是股票登录名/ ApplicationUserManager / ApplicationSignInManager方法,而我们的父应用程序有很多定制的OWIN。

Where a stock MVC site's login method uses: "SignInManager.PasswordSignInAsync(...)" 股票MVC网站的登录方法使用的地方: “ SignInManager.PasswordSignInAsync(...)”

our parent site is using: "HttpContext.GetOwinContext().Authentication.SignIn(...)" 我们的父站点正在使用: “ HttpContext.GetOwinContext()。Authentication.SignIn(...)”

Parent site still uses: "@User.Identity.GetUserName()" in the _loginPartial.cshtml just like the mostly stock MVC5 child site but the child NEVER picks up the Identity.User or any User Claims from the parent like the stock MVC5 parent/child sites do. 父站点仍然使用:_loginPartial.cshtml中的“ @ User.Identity.GetUserName()” ,就像大多数MVC5子站点一样,但是子站点从不从父MVC5父站点中获取Identity.User或任何用户声明,例如MVC5父站点/ child网站。

Here is some of the login: 以下是一些登录信息:

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 goes to the Db and verifies the creds _ProfileService.Login转到Db并验证凭据

here is the Startup.Auth.cs: 这是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();
    }

There is some code in the startup to handle when our site ajax's to twillio so it doesn't extend their session as if they are navigating. 启动时有一些代码可以处理我们的站点ajax到twillio的时间,因此不会像导航时那样扩展它们的会话。

I found the answer. 我找到了答案。

  1. I needed to copy over the entire customized app.UseCookieAuthentication(... portion into the StartupAuth.cs file. The parent is giving the cookie a 'Name' property and apparently, it needs the same name in both apps. 我需要将整个定制的app.UseCookieAuthentication(...部分复制到app.UseCookieAuthentication(...文件中。父级为cookie提供了“名称”属性,显然,两个应用程序中都需要相同的名称。

  2. the following needs to be in the OnApplicationStarted() method of our custom setup: AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier; 我们的自定义设置的OnApplicationStarted()方法中需要包含以下内容: AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

Our architect set this up for Ninject by having our global.asax.cs inherit form a file called 'ParentApplication.cs" in the App_Startup folder. There, the ParentApplication.cs file inherits from NinjectHttpApplication. 我们的架构师通过让我们的global.asax.cs继承自App_Startup文件夹中名为“ ParentApplication.cs”的文件来为Ninject进行设置,在那里,ParentApplication.cs文件继承自NinjectHttpApplication。

In this file there is a method: 此文件中有一个方法:

protected override void OnApplicationStarted()

Hope this helps someone else. 希望这对其他人有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM