簡體   English   中英

IIS中使用OWIN的MVC父/子站點未傳遞身份

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

我需要將一個站點嵌套在IIS中的另一個站點之下,以便用戶可以在兩個站點之間來回切換而無需登錄到兩個站點。 之前,我通過刪除子級的大部分web.config使其成功地與MVC站點一起完成,因此它繼承了父級web.config並在父級配置中手動設置了計算機密鑰。

在父母中,我手動設置機器密鑰,並驗證孩子正在拿起它。

我已經使用個人用戶帳戶(身份)測試了兩個MVC 5 Web應用程序。 我使用相同的應用程序池將第二個應用程序設置為主應用程序下的虛擬應用程序。 股票的MVC應用程序可以正常工作。 我登錄到父級,導航到該子級,然后它識別了身份。 我可以驗證,因為在父站點和子站點中都顯示“ welcome bdamore@xxxxxx.com”。

但是股票交易者使用的是股票登錄名/ ApplicationUserManager / ApplicationSignInManager方法,而我們的父應用程序有很多定制的OWIN。

股票MVC網站的登錄方法使用的地方: “ SignInManager.PasswordSignInAsync(...)”

我們的父站點正在使用: “ HttpContext.GetOwinContext()。Authentication.SignIn(...)”

父站點仍然使用:_loginPartial.cshtml中的“ @ User.Identity.GetUserName()” ,就像大多數MVC5子站點一樣,但是子站點從不從父MVC5父站點中獲取Identity.User或任何用戶聲明,例如MVC5父站點/ child網站。

以下是一些登錄信息:

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轉到Db並驗證憑據

這是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(...部分復制到app.UseCookieAuthentication(...文件中。父級為cookie提供了“名稱”屬性,顯然,兩個應用程序中都需要相同的名稱。

  2. 我們的自定義設置的OnApplicationStarted()方法中需要包含以下內容: AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

我們的架構師通過讓我們的global.asax.cs繼承自App_Startup文件夾中名為“ ParentApplication.cs”的文件來為Ninject進行設置,在那里,ParentApplication.cs文件繼承自NinjectHttpApplication。

此文件中有一個方法:

protected override void OnApplicationStarted()

希望這對其他人有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM