4

Can an application create a PrincipalContext once and then reused it for the lifetime of the application? That would avoid the performance hit of recreating PrincipalContext with the same details before each call to Active Directory.

Can a PrincipalContext enter a bad state where it will no longer work?

James Newton-King
  • 48,174
  • 24
  • 109
  • 130

2 Answers2

2

As long as you are not accessing the PrincipalContext or the objects you get from it by multiple threads you should be able to keep the same context throughout the lifetime of the application.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • Can multiple threads not use a PrincipalContext at the same time? – James Newton-King Sep 05 '16 at 02:15
  • No, multiple threads can not. If the documentation does not specifically say it is safe to use from multiple threads you should assume all classes are not safe to be used by multiple threads directly or indirectly (like manipulating multiple `UserContext` objects from multiple threads also can break your underlying `PrincipalContext` that they all share) – Scott Chamberlain Sep 05 '16 at 02:34
1

Nothing in the nature of the class or its documentation suggests that it has a limited lifetime.

MSDN doesn't mention that it is thread safe, however i can't spot any mutable properties or methods that would mutate the object state (EDIT : apart from the Dispose() method), which basically suggests that it might be fine to use across multiple threads. Although the underlying Getters or methods could return thread contextual results which might not be the behaviour you are after.

EDIT :

I quote MSDN Magazine January 2008 (.NET 3.5) and i doubt this has changed

In the .NET Framework 3.5, AccountManagement delivers both the power and ease of use offered by the ActiveDirectoryMembershipProvider implementation in ASP.NET to programmers working in any environment. Additionally, the AccountManagement namespace allows you to authenticate credentials against the local SAM database if needed.

The two ValidateCredentials methods on the PrincipalContext class provide credential validation. You first create an instance of a PrincipalContext using the directory you wish to validate against and specify the appropriate options. After getting context, you test whether ValidateCredentials returns true or false based on the supplied user name and password values. Figure 12 shows an example of authenticating a user in AD LDS.

Figure 12 Authenticating a User in AD LDS (Close Figure 12) // establish context with AD LDS PrincipalContext ldsContext = new PrincipalContext( ContextType.ApplicationDirectory, "sea-dc-02.fabrikam.com:50000", "ou=ADAM Users,O=Microsoft,C=US");

// determine whether a user can validate to the directory Console.WriteLine( ldsContext.ValidateCredentials( "user1@adam", "Password1", ContextOptions.SimpleBind + ContextOptions.SecureSocketLayer));

This approach is most useful when you want to validate many different sets of user credentials quickly and efficiently. You create a single PrincipalContext object for the directory store in question and reuse that object instance for each call to ValidateCredentials. The PrincipalContext can reuse the connection to the directory, which results in good performance and scalability. And calls to ValidateCredentials are thread-safe, so your instance can be used across threads for this operation. It's important to note that the credentials used to create the PrincipalContext are not changed by calls to ValidateCredentials—the context and method call maintain separate connections.

sm_
  • 2,572
  • 2
  • 17
  • 34
  • It is basicly like the `SqlConnection` object, it gets passed into other classes which uses it's internal state. If you have multiple classes that take in a `PrincipalContext` all try to use it at the same time it will break just like a `SqlConnection` will break if you have multiple `SqlCommand` objects trying to use the connection at once. – Scott Chamberlain Sep 05 '16 at 02:55
  • 1
    @ScottChamberlain is this behaviour verified by testing ? I think Calls to ValidateCredintials are perfectly thread safe, i have an article mentioning that, i am trying to find the MSDN reference backing it. http://muraliimohanb.blogspot.com.au/2010/05/managing-directory-security-principals.html – sm_ Sep 05 '16 at 02:59
  • While MSDN Magazine is a good source, I see no mention of it being thread safe to use multiple threads in the official documentation for the [class](https://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.principalcontext(v=vs.110).aspx#Anchor_7) or the two overloads of the ValidateCredentials method. And even if ValidateCredentials is thread safe, that does not guarantee that a call to [`Principal.Save()`](https://msdn.microsoft.com/en-us/library/bb354074(v=vs.110).aspx) on two objects that share a `PrincipalContext` is safe to do. – Scott Chamberlain Sep 05 '16 at 03:36
  • Also, [see here for a example](http://stackoverflow.com/questions/630566/strange-error-when-using-system-directoryservices-accountmanagement-principalcon) of when it can go wrong. – Scott Chamberlain Sep 05 '16 at 03:38
  • 1
    @ScottChamberlain Am not sure why would it not be safe, since its just adding to a store/moving between stores. The example you attached has no documented backing on what causes the problem, the guy claims to have used a new instance at every call and still faced issues. – sm_ Sep 05 '16 at 04:26
  • -1: 4 years later, working on a legacy application and looking for any information about PrincipalContext. I found this https://social.msdn.microsoft.com/Forums/vstudio/en-US/66899307-2453-44c8-a7d0-04bdf7355ab9/principalcontext-lifetime-and-caching?forum=netfxbcl . I know it's old (even though it's more recent than the 2008 article quoted), but I don't think things changed. You should not cache it _even if_ you guarantee thread safety with a lock. – marco6 Apr 01 '20 at 08:39
  • @marco6 i can see you've found another source with a different answer, my answer doesn't do anything beyond stating facts, it doesn't suggest what you do with the object, but rather quotes from a link that is an MSDN article, so i don't understand the -1. I will update the answer with the link from your comment and a the new input. – sm_ Apr 02 '20 at 03:25
  • Once you update the article, I will remove the downvote – marco6 Apr 03 '20 at 07:10
  • 1
    I think this is the article: https://learn.microsoft.com/en-us/archive/msdn-magazine/2008/january/managing-directory-security-principals-in-the-net-framework-3-5 – Psddp Jun 30 '20 at 13:49