Exemple #1
0
        private static UserInfo GetOrCreateCachedUserInfo(JwtSecurityToken jwt, PortalSettings portalSettings, System.Security.Claims.Claim userClaim)
        {
            var usernamePrefixEnabled = bool.Parse(AzureConfig.GetSetting(AzureConfig.ServiceName, "UsernamePrefixEnabled", portalSettings.PortalId, "true"));
            var usernameToFind        = usernamePrefixEnabled ? $"azureb2c-{userClaim.Value}" : userClaim.Value;
            var userInfo = UserController.GetUserByName(portalSettings.PortalId, usernameToFind);
            var tokenKey = ComputeSha256Hash(jwt.RawData);
            var cache    = DotNetNuke.Services.Cache.CachingProvider.Instance();

            if (string.IsNullOrEmpty((string)cache.GetItem($"SyncB2CToken|{tokenKey}")))
            {
                var azureClient = new AzureClient(portalSettings.PortalId, AuthMode.Login)
                {
                    JwtIdToken = jwt
                };
                azureClient.SetAuthTokenInternal(jwt.RawData);
                azureClient.SetAutoMatchExistingUsers(true);
                var userData = azureClient.GetCurrentUserInternal(jwt);
                if (userInfo == null)
                {
                    // If user doesn't exist, create the user
                    userInfo                     = userData.ToUserInfo(usernamePrefixEnabled);
                    userInfo.PortalID            = portalSettings.PortalId;
                    userInfo.Membership.Password = UserController.GeneratePassword();
                    var result = UserController.CreateUser(ref userInfo);
                }

                azureClient.AuthenticateUser(userData, portalSettings, HttpContext.Current.Request["REMOTE_ADDR"], azureClient.AddCustomProperties, azureClient.OnUserAuthenticated);
                azureClient.UpdateUserProfile(jwt, false, false);
                cache.Insert($"SyncB2CToken|{tokenKey}", "OK", null, jwt.ValidTo, TimeSpan.Zero);
            }

            return(userInfo);
        }
        public override void AuthenticateUser(UserData user, PortalSettings settings, string IPAddress, Action <NameValueCollection> addCustomProperties, Action <UserAuthenticatedEventArgs> onAuthenticated)
        {
            var portalSettings = settings;

            if (IsCurrentUserAuthorized() && JwtIdToken != null)
            {
                // Check if portalId profile mapping exists
                var portalUserMapping = UserMappingsRepository.Instance.GetUserMapping("PortalId", GetCalculatedPortalId());
                if (!string.IsNullOrEmpty(portalUserMapping?.B2cClaimName))
                {
                    var claimName = portalUserMapping?.GetB2cCustomClaimName();
                    // Get PortalId from claim
                    var portalIdClaim = JwtIdToken.Claims.FirstOrDefault(x => x.Type.ToLowerInvariant() == claimName.ToLowerInvariant())?.Value;
                    if (string.IsNullOrEmpty(portalIdClaim))
                    {
                        throw new SecurityTokenException("The user has no portalId claim and portalId profile mapping is setup. The B2C user can't login to any portal until the portalId attribute has been setup for the user. Ensure that the PortalId claim has been setup and included on the policy being used.");
                    }
                    if (int.TryParse(portalIdClaim, out int portalId) && portalId != portalSettings.PortalId)
                    {
                        // Redirect to the user portal
                        var request = HttpContext.Current.Request;
                        if (!string.IsNullOrEmpty(request.Headers["Authorization"]) && request.Headers["Authorization"].StartsWith("Bearer"))
                        {
                            throw new SecurityTokenException($"The user portalId claim ({portalId}) is different from current portalId ({portalSettings.PortalId}). Portal redirection flow is not supported on native apps. Please call the API from the corresponding portal URL");
                        }
                        var state = new State(request["state"]);
                        HttpContext.Current.Response.Redirect(Utils.GetLoginUrl(portalId, state.Culture, request));
                        return;
                    }
                }
            }

            var userIdClaim = Utils.GetUserIdClaim(GetCalculatedPortalId());
            var userClaim   = JwtIdToken.Claims.FirstOrDefault(x => x.Type == userIdClaim);

            if (userClaim == null)
            {
                if (Logger.IsDebugEnabled)
                {
                    Logger.Error($"Can't find '{userIdClaim}' claim on token");
                }
                throw new MissingFieldException($"Can't find '{userIdClaim}' claim on token, needed to identify the user");
            }

            var usernamePrefixEnabled = bool.Parse(AzureConfig.GetSetting(AzureConfig.ServiceName, "UsernamePrefixEnabled", portalSettings.PortalId, "true"));
            var usernameToFind        = usernamePrefixEnabled ? $"azureb2c-{userClaim.Value}" : userClaim.Value;
            var userInfo = UserController.GetUserByName(portalSettings.PortalId, usernameToFind);

            // If user doesn't exist on current portal, AuthenticateUser() will create it.
            // Otherwise, AuthenticateUser will perform a Response.Redirect, so we have to sinchronize the roles before that, to avoid the ThreadAbortException caused by the Response.Redirect
            if (userInfo == null)
            {
                base.AuthenticateUser(user, portalSettings, IPAddress, addCustomProperties, onAuthenticated);
                if (IsCurrentUserAuthorized())
                {
                    userInfo = UserController.GetUserByName(portalSettings.PortalId, usernameToFind);
                    if (userInfo == null)
                    {
                        throw new SecurityTokenException($"The logged in user {usernameToFind} does not belong to PortalId {portalSettings.PortalId}");
                    }
                    UpdateUserAndRoles(userInfo);
                    MarkUserAsB2c(userInfo);
                }
            }
            else
            {
                if (IsCurrentUserAuthorized())
                {
                    UpdateUserAndRoles(userInfo);
                    MarkUserAsB2c(userInfo);
                }
                base.AuthenticateUser(user, portalSettings, IPAddress, addCustomProperties, onAuthenticated);
            }
        }