protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
                LblTitle.Text = String.Format("AzureCP v{0} - <a href=\"https://github.com/Yvand/AzureCP\" target=\"_blank\">GitHub.com/Yvand/AzureCP</a>", fvi.FileVersion);
            }

            // Get trust currently associated with AzureCP, if any
            CurrentTrustedLoginProvider = AzureCP.GetSPTrustAssociatedWithCP(AzureCP._ProviderInternalName);
            if (null == CurrentTrustedLoginProvider)
            {
                // Claim provider is currently not associated with any trust.
                // Display a message in the page and disable controls
                this.LabelErrorMessage.Text     = TextErrorNoTrustAssociation;
                this.BtnOK.Enabled              = this.BtnOKTop.Enabled = this.BtnAddLdapConnection.Enabled = this.BtnTestAzureTenantConnection.Enabled = false;
                this.AllowPersistedObjectUpdate = false;
                return;
            }

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                // Get SPPersisted Object and create it if it doesn't exist
                PersistedObject = AzureCPConfig.GetFromConfigDB();
                if (PersistedObject == null)
                {
                    this.Web.AllowUnsafeUpdates = true;
                    PersistedObject             = AzureCPConfig.CreatePersistedObject();
                    this.Web.AllowUnsafeUpdates = false;
                }
            });

            this.IdentityClaim = PersistedObject.AzureADObjects.Find(x => String.Equals(CurrentTrustedLoginProvider.IdentityClaimTypeInformation.MappedClaimType, x.ClaimType, StringComparison.InvariantCultureIgnoreCase) && !x.CreateAsIdentityClaim);
            if (null == this.IdentityClaim)
            {
                // Identity claim type is missing in the attributes list
                this.LabelErrorMessage.Text = String.Format(this.TextErrorNoIdentityClaimType, CurrentTrustedLoginProvider.DisplayName, CurrentTrustedLoginProvider.IdentityClaimTypeInformation.MappedClaimType);
                this.BtnOK.Enabled          = this.BtnOKTop.Enabled = this.BtnAddLdapConnection.Enabled = this.BtnTestAzureTenantConnection.Enabled = false;
                return;
            }

            if (ViewState["PersistedObjectVersion"] == null)
            {
                ViewState.Add("PersistedObjectVersion", PersistedObject.Version);
            }
            if ((long)ViewState["PersistedObjectVersion"] != PersistedObject.Version)
            {
                // PersistedObject changed since last time. Should not allow any update
                this.LabelErrorMessage.Text     = TextErrorPersistedObjectStale;
                this.AllowPersistedObjectUpdate = false;
                return;
            }

            if (!this.IsPostBack)
            {
                PopulateFields();
            }
        }
示例#2
0
        void LnkDeleteItem_Command(object sender, CommandEventArgs e)
        {
            if (!this.AllowPersistedObjectUpdate)
            {
                return;
            }

            string        itemId = e.CommandArgument.ToString();
            AzureADObject attr   = ClaimsMapping.Find(x => x.Key == Convert.ToInt32(itemId)).Value;

            PersistedObject.AzureADObjects.Remove(attr);
            this.UpdatePersistedObject();
            this.BuildAttributesListTable(false);
        }
示例#3
0
        internal AzureADObject CopyPersistedProperties()
        {
            AzureADObject copy = new AzureADObject()
            {
                ClaimTypePersisted              = this.ClaimTypePersisted,
                GraphPropertyPersisted          = this.GraphPropertyPersisted,
                ClaimEntityTypePersisted        = this.ClaimEntityTypePersisted,
                EntityDataKeyPersisted          = this.EntityDataKeyPersisted,
                ClaimValueTypePersisted         = this.ClaimValueTypePersisted,
                CreateAsIdentityClaimPersisted  = this.CreateAsIdentityClaimPersisted,
                PrefixToBypassLookupPersisted   = this.PrefixToBypassLookupPersisted,
                GraphPropertyToDisplayPersisted = this.GraphPropertyToDisplayPersisted,
                FilterExactMatchOnlyPersisted   = this.FilterExactMatchOnlyPersisted,
                ClaimTypeMappingNamePersisted   = this.ClaimTypeMappingNamePersisted,
                PeoplePickerAttributeHierarchyNodeIdPersisted = this.PeoplePickerAttributeHierarchyNodeIdPersisted,
            };

            return(copy);
        }
示例#4
0
 internal AzureADObject CopyPersistedProperties()
 {
     AzureADObject copy = new AzureADObject()
     {
         ClaimTypePersisted = this.ClaimTypePersisted,
         GraphPropertyPersisted = this.GraphPropertyPersisted,
         ClaimEntityTypePersisted = this.ClaimEntityTypePersisted,
         EntityDataKeyPersisted = this.EntityDataKeyPersisted,
         ClaimValueTypePersisted = this.ClaimValueTypePersisted,
         CreateAsIdentityClaimPersisted = this.CreateAsIdentityClaimPersisted,
         PrefixToBypassLookupPersisted = this.PrefixToBypassLookupPersisted,
         GraphPropertyToDisplayPersisted = this.GraphPropertyToDisplayPersisted,
         FilterExactMatchOnlyPersisted = this.FilterExactMatchOnlyPersisted,
         ClaimTypeMappingNamePersisted = this.ClaimTypeMappingNamePersisted,
         PeoplePickerAttributeHierarchyNodeIdPersisted = this.PeoplePickerAttributeHierarchyNodeIdPersisted,
     };
     return copy;
 }
示例#5
0
        protected void BtnCreateNewItem_Click(object sender, EventArgs e)
        {
            AzureADObject azureObject = new AzureADObject();

            if (RdbNewItemClassicClaimType.Checked)
            {
                if (String.IsNullOrEmpty(New_TxtClaimType.Text))
                {
                    this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                    ShowNewItemForm             = true;
                    BuildAttributesListTable(false);
                    return;
                }

                azureObject.ClaimType = New_TxtClaimType.Text;

                if (PersistedObject.AzureADObjects.FirstOrDefault(x => String.Equals(x.ClaimType, azureObject.ClaimType, StringComparison.InvariantCultureIgnoreCase)) != null)
                {
                    this.LabelErrorMessage.Text = TextErrorDuplicateClaimType;
                    ShowNewItemForm             = true;
                    BuildAttributesListTable(false);
                    return;
                }
            }
            else if (RdbNewItemPermissionMetadata.Checked)
            {
                if (String.IsNullOrEmpty(New_DdlPermissionMetadata.SelectedValue))
                {
                    this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                    ShowNewItemForm             = true;
                    BuildAttributesListTable(false);
                    return;
                }
            }
            else
            {
                azureObject.CreateAsIdentityClaim = true;
            }

            if (!String.IsNullOrEmpty(New_DdlPermissionMetadata.SelectedValue) && !ClaimsMapping.FirstOrDefault(x => String.Equals(x.Value.EntityDataKey, New_DdlPermissionMetadata.SelectedValue, StringComparison.InvariantCultureIgnoreCase)).Equals(default(KeyValuePair <int, AzureADObject>)))
            {
                this.LabelErrorMessage.Text = String.Format(TextErrorNewMetadataAlreadyUsed, New_DdlPermissionMetadata.SelectedValue);
                ShowNewItemForm             = true;
                BuildAttributesListTable(false);
                return;
            }

            GraphProperty prop;
            bool          convertSuccess = Enum.TryParse <GraphProperty>(New_DdlGraphProperty.SelectedValue, out prop);

            if (!convertSuccess || prop == GraphProperty.None)
            {
                this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                ShowNewItemForm             = true;
                BuildAttributesListTable(false);
                return;
            }
            azureObject.GraphProperty          = prop;
            convertSuccess                     = Enum.TryParse <GraphProperty>(New_DdlGraphPropertyToDisplay.SelectedValue, out prop);
            azureObject.GraphPropertyToDisplay = convertSuccess ? prop : GraphProperty.None;
            azureObject.ClaimEntityType        = SPClaimEntityTypes.User;
            azureObject.EntityDataKey          = New_DdlPermissionMetadata.SelectedValue;

            PersistedObject.AzureADObjects.Add(azureObject);
            UpdatePersistedObject();
            BuildAttributesListTable(false);
        }
示例#6
0
        void LnkUpdateItem_Command(object sender, CommandEventArgs e)
        {
            if (!this.AllowPersistedObjectUpdate)
            {
                return;
            }

            string itemId = e.CommandArgument.ToString();

            NameValueCollection formData = Request.Form;

            if (String.IsNullOrEmpty(formData["input_claimtype_" + itemId]) || String.IsNullOrEmpty(formData["list_graphproperty_" + itemId]))
            {
                this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                return;
            }

            // Get object to update
            int           azureObjectId = Convert.ToInt32(itemId);
            AzureADObject azureObject   = ClaimsMapping.Find(x => x.Key == azureObjectId).Value;

            // Check if changes are OK
            // Check if claim type is not empty and not already used
            string newClaimType = formData["input_claimtype_" + itemId];

            if (newClaimType == String.Empty)
            {
                this.LabelErrorMessage.Text = TextErrorUpdateEmptyClaimType;
                BuildAttributesListTable(false);
                return;
            }
            List <KeyValuePair <int, AzureADObject> > otherAzureObjects = ClaimsMapping.FindAll(x => x.Key != azureObjectId);
            KeyValuePair <int, AzureADObject>         matchFound;

            matchFound = otherAzureObjects.FirstOrDefault(x => String.Equals(x.Value.ClaimType, newClaimType, StringComparison.InvariantCultureIgnoreCase));

            // Check if new claim type is not already used
            if (!matchFound.Equals(default(KeyValuePair <int, AzureADObject>)))
            {
                this.LabelErrorMessage.Text = String.Format(TextErrorUpdateItemDuplicate, azureObject.ClaimType, "claim type", newClaimType);
                BuildAttributesListTable(false);
                return;
            }

            // Check if new entity data key is not already used (we don't care about this check if it's empty)
            string newEntityDataKey = formData["list_Metadata_" + itemId];

            if (newEntityDataKey != String.Empty)
            {
                matchFound = otherAzureObjects.FirstOrDefault(x => String.Equals(x.Value.EntityDataKey, newEntityDataKey, StringComparison.InvariantCultureIgnoreCase));
                if (!matchFound.Equals(default(KeyValuePair <int, AzureADObject>)))
                {
                    this.LabelErrorMessage.Text = String.Format(TextErrorUpdateItemDuplicate, azureObject.ClaimType, "permission metadata", newEntityDataKey);
                    BuildAttributesListTable(false);
                    return;
                }
            }

            string newClaimEntityType = formData["list_ClaimEntityType_" + itemId];

            // Specific checks if current claim type is identity claim type
            if (String.Equals(azureObject.ClaimType, CurrentTrustedLoginProvider.IdentityClaimTypeInformation.MappedClaimType, StringComparison.InvariantCultureIgnoreCase))
            {
                // We don't allow to change claim type
                if (!String.Equals(azureObject.ClaimType, newClaimType, StringComparison.InvariantCultureIgnoreCase))
                {
                    this.LabelErrorMessage.Text = TextErrorUpdateIdentityClaimTypeChanged;
                    BuildAttributesListTable(false);
                    return;
                }

                // ClaimEntityType must be "SPClaimEntityTypes.User"
                if (!String.Equals(SPClaimEntityTypes.User, newClaimEntityType, StringComparison.InvariantCultureIgnoreCase))
                {
                    this.LabelErrorMessage.Text = TextErrorUpdateIdentityClaimEntityTypeNotUser;
                    BuildAttributesListTable(false);
                    return;
                }
            }

            azureObject.ClaimType            = newClaimType;
            azureObject.ClaimEntityType      = newClaimEntityType;
            azureObject.PrefixToBypassLookup = formData["input_PrefixToBypassLookup_" + itemId];
            azureObject.EntityDataKey        = newEntityDataKey;

            GraphProperty prop;
            bool          convertSuccess = Enum.TryParse <GraphProperty>(formData["list_graphproperty_" + itemId], out prop);

            azureObject.GraphProperty = convertSuccess ? prop : azureObject.GraphProperty;

            convertSuccess = Enum.TryParse <GraphProperty>(formData["list_GraphPropertyToDisplay_" + itemId], out prop);
            azureObject.GraphPropertyToDisplay = convertSuccess ? prop : azureObject.GraphPropertyToDisplay;

            this.UpdatePersistedObject();
            this.BuildAttributesListTable(false);
        }
示例#7
0
文件: AzureCP.cs 项目: Yvand/AzureCP
 protected virtual PickerEntity CreatePickerEntityForSpecificClaimType(string input, AzureADObject claimTypesToResolve, bool inputHasKeyword)
 {
     List<PickerEntity> entities = CreatePickerEntityForSpecificClaimTypes(
         input,
         new List<AzureADObject>()
             {
                 claimTypesToResolve,
             },
         inputHasKeyword);
     return entities == null ? null : entities.First();
 }
示例#8
0
文件: AzureCP.cs 项目: Yvand/AzureCP
        /// <summary>
        /// Initializes claim provider. This method is reserved for internal use and is not intended to be called from external code or changed
        /// </summary>
        /// <param name="AzureADObjects"></param>
        /// <returns></returns>
        private bool ProcessAzureADObjectCollection(List<AzureADObject> AzureADObjectCollection)
        {
            bool success = true;
            try
            {
                bool identityClaimTypeFound = false;
                // Get attributes defined in trust based on their claim type (unique way to map them)
                List<AzureADObject> claimTypesSetInTrust = new List<AzureADObject>();
                // There is a bug in the SharePoint API: SPTrustedLoginProvider.ClaimTypes should retrieve SPTrustedClaimTypeInformation.MappedClaimType, but it returns SPTrustedClaimTypeInformation.InputClaimType instead, so we cannot rely on it
                //foreach (var attr in _AttributesDefinitionList.Where(x => AssociatedSPTrustedLoginProvider.ClaimTypes.Contains(x.claimType)))
                //{
                //    attributesDefinedInTrust.Add(attr);
                //}
                foreach (SPTrustedClaimTypeInformation ClaimTypeInformation in SPTrust.ClaimTypeInformation)
                {
                    // Search if current claim type in trust exists in AzureADObjects
                    // List<T>.FindAll returns an empty list if no result found: http://msdn.microsoft.com/en-us/library/fh1w7y8z(v=vs.110).aspx
                    List<AzureADObject> azureObjectColl = AzureADObjectCollection.FindAll(x =>
                        String.Equals(x.ClaimType, ClaimTypeInformation.MappedClaimType, StringComparison.InvariantCultureIgnoreCase) &&
                        !x.CreateAsIdentityClaim &&
                        x.GraphProperty != GraphProperty.None);
                    AzureADObject azureObject;
                    if (azureObjectColl.Count == 1)
                    {
                        azureObject = azureObjectColl.First();
                        claimTypesSetInTrust.Add(azureObject);

                        if (String.Equals(SPTrust.IdentityClaimTypeInformation.MappedClaimType, azureObject.ClaimType, StringComparison.InvariantCultureIgnoreCase))
                        {
                            // Identity claim type found, set IdentityAzureADObject property
                            identityClaimTypeFound = true;
                            IdentityAzureObject = azureObject;
                        }
                    }
                }

                // Check if identity claim is there. Should always check property SPTrustedClaimTypeInformation.MappedClaimType: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.claims.sptrustedclaimtypeinformation.mappedclaimtype.aspx
                if (!identityClaimTypeFound)
                {
                    AzureCPLogging.Log(String.Format("[{0}] Impossible to continue because identity claim type \"{1}\" set in the SPTrustedIdentityTokenIssuer \"{2}\" is missing in AzureADObjects.", ProviderInternalName, SPTrust.IdentityClaimTypeInformation.MappedClaimType, SPTrust.Name), TraceSeverity.Unexpected, EventSeverity.ErrorCritical, AzureCPLogging.Categories.Core);
                    return false;
                }

                // This check is to find if there is a duplicate of the identity claim type that uses the same GraphProperty
                //AzureADObject objectToDelete = claimTypesSetInTrust.Find(x =>
                //    !String.Equals(x.ClaimType, SPTrust.IdentityClaimTypeInformation.MappedClaimType, StringComparison.InvariantCultureIgnoreCase) &&
                //    !x.CreateAsIdentityClaim &&
                //    x.GraphProperty == GraphProperty.UserPrincipalName);
                //if (objectToDelete != null) claimTypesSetInTrust.Remove(objectToDelete);

                // Check if there are objects that should be always queried (CreateAsIdentityClaim) to add in the list
                List<AzureADObject> additionalObjects = new List<AzureADObject>();
                foreach (AzureADObject attr in AzureADObjectCollection.Where(x => x.CreateAsIdentityClaim))// && !claimTypesSetInTrust.Contains(x, new LDAPPropertiesComparer())))
                {
                    // Check if identity claim type is already using same GraphProperty, and ignore current object if so
                    if (IdentityAzureObject.GraphProperty == attr.GraphProperty) continue;

                    // Normally ClaimType should be null if CreateAsIdentityClaim is set to true, but we check here it and handle this scenario
                    if (!String.IsNullOrEmpty(attr.ClaimType))
                    {
                        if (String.Equals(SPTrust.IdentityClaimTypeInformation.MappedClaimType, attr.ClaimType))
                        {
                            // Not a big deal since it's set with identity claim type, so no inconsistent behavior to expect, just record an information
                            AzureCPLogging.Log(String.Format("[{0}] Object with GraphProperty {1} is set with CreateAsIdentityClaim to true and ClaimType {2}. Remove ClaimType property as it is useless.", ProviderInternalName, attr.GraphProperty, attr.ClaimType), TraceSeverity.Monitorable, EventSeverity.Information, AzureCPLogging.Categories.Core);
                        }
                        else if (claimTypesSetInTrust.Count(x => String.Equals(x.ClaimType, attr.ClaimType)) > 0)
                        {
                            // Same claim type already exists with CreateAsIdentityClaim == false.
                            // Current object is a bad one and shouldn't be added. Don't add it but continue to build objects list
                            AzureCPLogging.Log(String.Format("[{0}] Claim type {1} is defined twice with CreateAsIdentityClaim set to true and false, which is invalid. Remove entry with CreateAsIdentityClaim set to true.", ProviderInternalName, attr.ClaimType), TraceSeverity.Monitorable, EventSeverity.Information, AzureCPLogging.Categories.Core);
                            continue;
                        }
                    }

                    attr.ClaimType = SPTrust.IdentityClaimTypeInformation.MappedClaimType;    // Give those objects the identity claim type
                    attr.ClaimEntityType = SPClaimEntityTypes.User;
                    attr.GraphPropertyToDisplay = IdentityAzureObject.GraphPropertyToDisplay; // Must be set otherwise display text of permissions will be inconsistent
                    additionalObjects.Add(attr);
                }

                ProcessedAzureObjects = new List<AzureADObject>(claimTypesSetInTrust.Count + additionalObjects.Count);
                ProcessedAzureObjects.AddRange(claimTypesSetInTrust);
                ProcessedAzureObjects.AddRange(additionalObjects);

                // Parse objects to configure some settings
                // An object can have ClaimType set to null if only used to populate metadata of permission created
                foreach (var attr in ProcessedAzureObjects.Where(x => x.ClaimType != null))
                {
                    var trustedClaim = SPTrust.GetClaimTypeInformationFromMappedClaimType(attr.ClaimType);
                    // It should never be null
                    if (trustedClaim == null) continue;
                    attr.ClaimTypeMappingName = trustedClaim.DisplayName;
                }

                // Any metadata for a user with GraphProperty actually set is valid
                this.ProcessedAzureObjectsMetadata = AzureADObjectCollection.FindAll(x =>
                    !String.IsNullOrEmpty(x.EntityDataKey) &&
                    x.GraphProperty != GraphProperty.None &&
                    x.ClaimEntityType == SPClaimEntityTypes.User);
            }
            catch (Exception ex)
            {
                AzureCPLogging.LogException(ProviderInternalName, "while processing AzureADObjects", AzureCPLogging.Categories.Core, ex);
                success = false;
            }
            return success;
        }
示例#9
0
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
                LblTitle.Text = String.Format("AzureCP v{0} - <a href=\"https://github.com/Yvand/AzureCP\" target=\"_blank\">GitHub.com/Yvand/AzureCP</a>", fvi.FileVersion);
            }

            // Get trust currently associated with AzureCP, if any
            CurrentTrustedLoginProvider = AzureCP.GetSPTrustAssociatedWithCP(AzureCP._ProviderInternalName);
            if (null == CurrentTrustedLoginProvider)
            {
                // Claim provider is currently not associated with any trust.
                // Display a message in the page and disable controls
                this.LabelErrorMessage.Text = TextErrorNoTrustAssociation;
                this.BtnOK.Enabled = this.BtnOKTop.Enabled = this.BtnAddLdapConnection.Enabled = this.BtnTestAzureTenantConnection.Enabled = false;
                this.AllowPersistedObjectUpdate = false;
                return;
            }

            SPSecurity.RunWithElevatedPrivileges(delegate ()
            {
                // Get SPPersisted Object and create it if it doesn't exist
                PersistedObject = AzureCPConfig.GetFromConfigDB();
                if (PersistedObject == null)
                {
                    this.Web.AllowUnsafeUpdates = true;
                    PersistedObject = AzureCPConfig.CreatePersistedObject();
                    this.Web.AllowUnsafeUpdates = false;
                }
            });

            this.IdentityClaim = PersistedObject.AzureADObjects.Find(x => String.Equals(CurrentTrustedLoginProvider.IdentityClaimTypeInformation.MappedClaimType, x.ClaimType, StringComparison.InvariantCultureIgnoreCase) && !x.CreateAsIdentityClaim);
            if (null == this.IdentityClaim)
            {
                // Identity claim type is missing in the attributes list
                this.LabelErrorMessage.Text = String.Format(this.TextErrorNoIdentityClaimType, CurrentTrustedLoginProvider.DisplayName, CurrentTrustedLoginProvider.IdentityClaimTypeInformation.MappedClaimType);
                this.BtnOK.Enabled = this.BtnOKTop.Enabled = this.BtnAddLdapConnection.Enabled = this.BtnTestAzureTenantConnection.Enabled = false;
                return;
            }

            if (ViewState["PersistedObjectVersion"] == null)
                ViewState.Add("PersistedObjectVersion", PersistedObject.Version);
            if ((long)ViewState["PersistedObjectVersion"] != PersistedObject.Version)
            {
                // PersistedObject changed since last time. Should not allow any update
                this.LabelErrorMessage.Text = TextErrorPersistedObjectStale;
                this.AllowPersistedObjectUpdate = false;
                return;
            }

            if (!this.IsPostBack)
            {
                PopulateFields();
            }
        }
示例#10
0
        protected void BtnCreateNewItem_Click(object sender, EventArgs e)
        {
            AzureADObject azureObject = new AzureADObject();
            if (RdbNewItemClassicClaimType.Checked)
            {
                if (String.IsNullOrEmpty(New_TxtClaimType.Text))
                {
                    this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                    ShowNewItemForm = true;
                    BuildAttributesListTable(false);
                    return;
                }

                azureObject.ClaimType = New_TxtClaimType.Text;

                if (PersistedObject.AzureADObjects.FirstOrDefault(x => String.Equals(x.ClaimType, azureObject.ClaimType, StringComparison.InvariantCultureIgnoreCase)) != null)
                {
                    this.LabelErrorMessage.Text = TextErrorDuplicateClaimType;
                    ShowNewItemForm = true;
                    BuildAttributesListTable(false);
                    return;
                }
            }
            else if (RdbNewItemPermissionMetadata.Checked)
            {
                if (String.IsNullOrEmpty(New_DdlPermissionMetadata.SelectedValue))
                {
                    this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                    ShowNewItemForm = true;
                    BuildAttributesListTable(false);
                    return;
                }
            }
            else azureObject.CreateAsIdentityClaim = true;

            if (!String.IsNullOrEmpty(New_DdlPermissionMetadata.SelectedValue) && !ClaimsMapping.FirstOrDefault(x => String.Equals(x.Value.EntityDataKey, New_DdlPermissionMetadata.SelectedValue, StringComparison.InvariantCultureIgnoreCase)).Equals(default(KeyValuePair<int, AzureADObject>)))
            {
                this.LabelErrorMessage.Text = String.Format(TextErrorNewMetadataAlreadyUsed, New_DdlPermissionMetadata.SelectedValue);
                ShowNewItemForm = true;
                BuildAttributesListTable(false);
                return;
            }

            GraphProperty prop;
            bool convertSuccess = Enum.TryParse<GraphProperty>(New_DdlGraphProperty.SelectedValue, out prop);
            if (!convertSuccess || prop == GraphProperty.None)
            {
                this.LabelErrorMessage.Text = TextErrorFieldsMissing;
                ShowNewItemForm = true;
                BuildAttributesListTable(false);
                return;
            }
            azureObject.GraphProperty = prop;
            convertSuccess = Enum.TryParse<GraphProperty>(New_DdlGraphPropertyToDisplay.SelectedValue, out prop);
            azureObject.GraphPropertyToDisplay = convertSuccess ? prop : GraphProperty.None;
            azureObject.ClaimEntityType = SPClaimEntityTypes.User;
            azureObject.EntityDataKey = New_DdlPermissionMetadata.SelectedValue;

            PersistedObject.AzureADObjects.Add(azureObject);
            UpdatePersistedObject();
            BuildAttributesListTable(false);
        }