1

The UserPrincipal.FindByIdentity(…) method does not work cross domain. the users outside of the domain the SingleSignOn app pool is running as are not being signed in automatically. When trying to access the SingleSignOn page as one of those users, it presents a NullReferenceException error


Srs
  • 53
  • 5
  • 1
    Hi, this question is in danger of being closed as a duplicate of [the canonical NullReference exception question](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it?rq=1). Where do you get the exception? You mentioned the method you're using doesn't work for the purpose you're using it, is that _why_ you get the exception? And what's your question, anyway - you say something "does not work" and you "get an error" - how are you expecting us to be able to help you? What kind of domain is this anyway? An AD forest? Something else? – stuartd Feb 11 '20 at 00:55
  • `new PrincipalContext(ContextType.Domain)` defines the context to be the same domain as the user's domain thats running the script. Not sure how its supposed to go out to a different domain when you are Specifying the domain to be local to user's. If you search for account that doesnt exist, you will have a null, and any reference to that account will produce `NullReferenceException` – Jawad Feb 11 '20 at 01:43
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – theminer3746 Feb 11 '20 at 02:51
  • @Jawad what method/command should I use instead of new PrincipalContext(contextType.Domain) to load the user in different domains? – Srs Feb 11 '20 at 06:30
  • @stuartd yes, AD forest. Consider there are few domains throughout user base. users outside of one domain the SingleSignOn app pool is running as, are not being signed in automatically. And when these users try to access the SingleSignOn page, it shows a Null Reference exception error. As far as my search on google, i think UserPrincipal.FindByIdentity works only for one domain but not cross domain. So I need to know which method works for the cross domain? I hope this is more clear. Thanks! – Srs Feb 11 '20 at 06:49
  • _"it shows a Null Reference exception error"_ - because you're not checking if the `user` returned is null. – stuartd Feb 11 '20 at 11:05

1 Answers1

2

If you want to have a method that checks user in various domains, you will have to loop through various domains (with users that have access to read through each domain).

If you do have the domain information available of the user, you can add the domain as an argument to your method.

I am not sure if the AuthUserSession has any property that might hold the user's domain as well. If it does, use that instead of the domainName argument passed in to the method.

public void LoadUserAuthInfo(AuthUserSession userSession, IAuthTokens tokens, Dictionary<string, string> authInfo, string domainName= someDefaultIfNoneProvided)
{
  if (userSession == null)
        return;
  string lookup = userSession.Id;
  List<string> domains = new List<string>() { "domain1", "domain2" };
  bool userFound = false;

  foreach (string domain in domains)  
  {
    using (var pc = new PrincipalContext(ContextType.Domain, domain))
    {
       var user = UserPrincipal.FindByIdentity(pc, userSession.UserAuthName);

       // ---> Add Check here to prevent NRE
       if (user != null) {
           SingleSignOnResponse ssoB = new SingleSignOnResponse();
           ssoB.Username = user.Sid.Translate(typeof(NTAccount)).ToString();
           ssoB.Timestamp = DateTime.Now;
           SSOCache.Instance.TryAdd(lookup, ssoB);
           userFound = true;
           break; // No longer need to continue checking other domains.
       }
       else 
       {
           // Handle case when user does not exist.
       } 
    }
  }
  // Check if userFound = false. If so, do something with that exception.
}

Update

If you have the domainName in the session.id, use the following,

string lookup = userSession.Id;
  using (var pc = new PrincipalContext(ContextType.Domain, lookup.Split('\\')[0]))
  {
  ...
Jawad
  • 9,801
  • 2
  • 18
  • 30
  • AuthUserSession doesn't have any property for the user domain. – Srs Feb 11 '20 at 18:54
  • if you dont know which domain the user is coming from, then you might have to loop through the known domains to check user's existence. – Jawad Feb 11 '20 at 19:12
  • Suggestion on how the code would look like with loop around each domain that you might have for a user. – Jawad Feb 11 '20 at 19:43
  • @SriCharan added an update with the code that would work with lookup that contains the domain in it. – Jawad Feb 13 '20 at 00:29
  • @SriCharan Use split instead of indexOf. IndexOf increases the number of things you have to do. – Jawad Feb 13 '20 at 00:30
  • after implementing changes i get principalServerDownException – Srs Feb 21 '20 at 22:24
  • `This exception is thrown when the API is unable to connect to the server` ... this is what that exception means. It seems like you dont have access to that domain controller from where you are running the script. – Jawad Feb 21 '20 at 22:26