Search code examples
c#.netactive-directorysingle-sign-onprincipalcontext

Find user how to method work cross domain c#


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



Solution

  • 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]))
      {
      ...