public static async Task <ClaimsIdentity> GenerateUserIdentityAsync(this IdentityUser user, UserManager <IdentityUser, long> manager)
        {
            //// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            //var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            //// Add custom user claims here
            //userIdentity.AddClaim(new Claim("InstitutionCode", WebUtils.WebUtilities.InstitutionCode));
            //return userIdentity;

            if (manager == null)
            {
                throw new ArgumentNullException("manager");
            }

            ClaimsIdentity claimsIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);

            claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToStringLookup(), "http://www.w3.org/2001/XMLSchema#string"));
            claimsIdentity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"));

            var instCode = WebUtilities.InstitutionCode;

            if (!string.IsNullOrWhiteSpace(instCode))
            {
                var queryProcessor = Utilities.QueryProcessor;
                var query          = new GetInstitutionByCodeQuery
                {
                    Code = instCode,
                };
                user.InstitutionCode      = instCode;
                user.InstitutionShortName = queryProcessor.Process(query)?.ShortName;
            }
            else
            {
                instCode = Utilities.INST_DEFAULT_CODE;
            }
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, $"{user.UserName}:{instCode}", "http://www.w3.org/2001/XMLSchema#string"));

            if (manager.SupportsUserSecurityStamp && !string.IsNullOrWhiteSpace(user.SecurityStamp))
            {
                claimsIdentity.AddClaim(new Claim(Constants.DefaultSecurityStampClaimType, user.SecurityStamp, "http://www.w3.org/2001/XMLSchema#string"));
            }

            SetLoggedInUsersPrivileges(user);

            if (manager.SupportsUserClaim)
            {
                claimsIdentity.AddClaims(await manager.GetClaimsAsync(user.Id));
            }
            WebUtilities.SetCurrentlyLoggedInUser(user);
            return(claimsIdentity);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets the institution code. This returns null IF HTTP context or request or session is not available.
        /// If we return null, then requestAvailable is false. If central, we return the default code
        /// </summary>
        /// <returns></returns>
        /// <exception cref="GeneralException"></exception>
        public virtual string GetInstitutionCode(out bool requestAvailable)
        {
            if (IsRequestAvailable(_httpContext))
            {
                string core = Utilities.INST_DEFAULT_CODE;
                requestAvailable = true;
                string instCode;
                var    httpSession = _httpContext.Session;
                var    routeData   = _httpContext.Request.RequestContext?.RouteData?.Values;
                if (routeData == null || routeData.Count < 2 || httpSession == null)
                {
                    // This can happen when we invoke this before MVC is activated.
                    #region Pre-MVC
                    if (routeData != null && routeData.ContainsKey("institution"))
                    {
                        return(Convert.ToString(routeData["institution"]));
                    }

                    var url     = GetThisPageUrl(false, false).ToLowerInvariant();
                    var siteUrl = ConfigurationHelper.GetSiteUrl().ToLowerInvariant();
                    url = url.Replace(siteUrl, string.Empty);
                    if (string.IsNullOrWhiteSpace(url))
                    {
                        return(core);
                    }

                    var segments = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                    switch (segments.Length)
                    {
                    // This code HEAVILY relies on the url templates setup in
                    // MultiTenancyFramework.Mvc.InstitutionRouteConfig.RegisterRoutes
                    case 1:
                        if (new[] { "home", "error" }.Contains(segments[0]))
                        {
                            instCode = core;
                        }
                        else
                        {
                            instCode = segments[0];
                        }
                        break;

                    case 2:
                        if (new[] { "home", "error" }.Contains(segments[1]))
                        {
                            instCode = segments[0];
                        }
                        else
                        {
                            instCode = core;
                        }
                        break;

                    case 3:
                        int id;
                        if (int.TryParse(segments[2], out id))
                        {
                            instCode = core;
                        }
                        else
                        {
                            instCode = segments[0];
                        }
                        break;

                    case 4:
                    default:
                        instCode = segments[0];
                        break;
                    }
                    #endregion
                }
                else
                {
                    #region MVC-Specific
                    instCode = Convert.ToString(routeData["institution"]) ?? core;
                    if (string.IsNullOrWhiteSpace(instCode) || instCode.Equals(core, StringComparison.OrdinalIgnoreCase))
                    {
                        return(core);
                    }

                    // The request may be from a non-existent institution, so we check if we have it in session
                    if (httpSession != null && httpSession[SS_CODE] != null)
                    {
                        var codeInSession = Convert.ToString(httpSession[SS_CODE]); //ClaimsPrincipal.Current.FindFirst("ic")?.Value; //
                        if (!instCode.Equals(codeInSession, StringComparison.OrdinalIgnoreCase))
                        {
                            var error = $"codeInSession ({codeInSession}) != instCode ({instCode}).";
                            var ex    = new LogOutUserException(error);
                            throw ex;
                        }
                        return(codeInSession);
                    }
                    #endregion
                }

                // if it's a tenant
                if (!string.IsNullOrWhiteSpace(instCode) && !instCode.Equals(core, StringComparison.OrdinalIgnoreCase))
                {
                    var query = new GetInstitutionByCodeQuery
                    {
                        Code = instCode,
                    };
                    var inst = Utilities.QueryProcessor.Process(query);
                    if (inst == null)
                    {
                        if (IsStaticResource())
                        {
                            instCode = core;
                        }
                        else
                        {
                            throw new GeneralException($"The code: {instCode} does not belong to any institution on our system.", ExceptionType.UnidentifiedInstitutionCode);
                        }
                    }
                }
                _httpContext.Request.RequestContext.RouteData.Values["institution"] = instCode;
                if (_httpContext.Session != null)
                {
                    _httpContext.Session[SS_CODE] = instCode;
                }

                return(instCode); // return inst.Code;
            }

            requestAvailable = false;
            return(null);
        }