This project has moved. For the latest updates, please go here.

Prefixes for groups

Jun 19, 2014 at 4:43 PM
Hi Yvan,

I installed the last version of LDAPCP but looks like I need more things to develop.
This is the list:
1. My people wanted to have a parallel search in the ADs, so I changed it in a parallel.Foreach (SearchObjectsInLDAP method). If you consider this as an improvment I'm happy to give you the code; in the same time it will help me not to do this change in the future versions, when I'll do an update.
2. I had to add a prefix for the AD groups. I've seen that there already exists this functionality in the claims mapping. I did some changes to the code, because I needed that my groups to be prefixed with the domain name, so I added a token {domain} which I replaced with the corresponding value. I have a question regarding this: is there a way to prefix the groups with the domain name, using a setting? or the custom solution is the only option? (Again, if you consider my solution can help for improvements, I'll be happy to share it because in the future I need to be updated with the last version of the LDAPCP).
Thanks a lot for the solution, I've learned a lot :). Your feedback will help me to validate if I'm on the right track with the custom developments that I had to add.

regards,
Cristina
Coordinator
Jun 20, 2014 at 10:13 AM
hello Cristina,
many thanks for your feedback :)
Regarding your points:
for 1) it's actually a very good idea! I never used this API before and I barely know it, so I would be happy to get your code (I guess there is more than just "parallel.Foreach" but again, I never used that) and test it by myself. I will definitely integrate it in the next version if it works.
for 2) yes it's already possible OOB with property AttributeHelper.PrefixToAddToValueReturned, which can be set in administration page > "Claims mapping" > column "Prefix to add to value returned"
cheers,
Yvan
Jun 23, 2014 at 1:09 PM
Hi Yvan,

The code I wrote for no. 1 is in this method
protected override bool SearchObjectsInLDAP(string filter, Uri context, string[] entityTypes, ref SearchResult[] LDAPSearchResults)).
#region Parallel foreach
            var lockResults = new object();
            var lockLogging = new object();
            var dsproperties = new string[ds.PropertiesToLoad.Count];
            ds.PropertiesToLoad.CopyTo(dsproperties, 0);

            Parallel.ForEach(directories, currentDirectory =>
            {
                using (new SPMonitoredScope(String.Format("[{0}] Connecting to LDAP server {1}", ProviderInternalName, currentDirectory.Path), 1000))
                {
                    try
                    {
                        var currentDirectorySearcher = new DirectorySearcher(ds.Filter, dsproperties)
                        {
                            SearchRoot = currentDirectory
                        };

                        using (var directoryResults = currentDirectorySearcher.FindAll())
                        {
                            if (directoryResults != null && directoryResults.Count > 0)
                            {
                                lock (lockResults)
                                {
                                    //this is a duplicated list of SearchResults beause I need to keep the net bios name correlated to the items
                                    foreach (SearchResult item in directoryResults)
                                    {
                                        LDAPSearchResultWrappers.Add(new LDAPSearchResultWrapper()
                                        {
                                            SearchResult = item,
                                            LDAPNetBiosName = currentDirectory.Properties["name"].Value.ToString()
                                        });
                                    }
                                    results.AddRange(directoryResults.OfType<SearchResult>());
                                }

                                lock (lockLogging)
                                {
                                    LogToULS(String.Format("[{0}] Got {1} result(s) from {2}", ProviderInternalName, directoryResults.Count.ToString(), currentDirectory.Path), TraceSeverity.Verbose, EventSeverity.Information, LdapcpLoggingService.Categories.LDAP_Lookup);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        lock (lockLogging)
                        {
                            LogToULS(String.Format("[{0}] Unexpected error during connection to LDAP server \"{1}\": {2}. Callstack: {3}", ProviderInternalName, currentDirectory.Path, ex.Message, ex.StackTrace), TraceSeverity.Unexpected, EventSeverity.Error, LdapcpLoggingService.Categories.LDAP_Lookup);
                        }
                    }
                    finally
                    {
                        //if (directoryResults != null) directoryResults.Dispose();
                        currentDirectory.Dispose();
                    }
                }
            });
            #endregion
This method has a bit more modifications because I implemented something else. (How can I send you all the implementation of the method? If it is necessary.)

For point no. 2 I have a case scenario like this:
  • I have 2 ADs: domain1 and domain2.
  • When I search for key: "Users", I'd like to see the next 2 entries: (Role) domain1\Users ... (Role) domain2\Users.
    If I use the OOTB implementation, what are the settings that I need to add in "Claims mapping"?
    For the moment I did a custom implementation and I'm using a token notation like {domain} which I replace in code with the corresponding domain name.
Thanks and cheers,
Cristina
Coordinator
Jun 25, 2014 at 7:58 AM
hello Cristina,

you can send the code by email to yvan84@live.com, it looks very promising, I will test this and let you know.

For point 2: this is a very specific need and indeed you can't do that with OOB version.
OOB the closest possibility that looks like what you need is:
  • search for "group:domain1\users" and it creates permission "domain1\users"
  • search for "group:domain2\users" and it creates permission "domain2\users"
    If it's not acceptable for you, then yes you need to use your customization.
cheers,
Yvan