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(); } }
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); }
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); }
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; }
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); }
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); }
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(); }
/// <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; }
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(); } }
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); }