'What causes UserPrincipal.Current to be defined?

I am troubleshooting with a vendor on a silent enrollment process. The process is failing because their code does not get a Guid from ADFS and therefore they say it a configuration issue in our environment. To demonstrate this, they wrote a small C# app that throws an exception on trying to access UserPrincipal.Current.Guid.

I reviewed their code and demonstrated that the Guid can be pulled successfully with an explicit initialization of the PrincipalContext and UserPrincipal. To me this shows that it is not a permissions or configuration issue with the environment, but them using outdated coding standards.

What has to happen for UserPrincipal.Current to have a defined value? or should it always have one for a logged in user if permissions are present?

Here is the code block in question:

try
{
    // Hardcode initialization of PrincipalContext
    PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain.local","DC=domain,DC=local");

    string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

    UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, userName);

    Console.WriteLine("User Guid Value after init: " + up.Guid.ToString());
                    
    string userGuid = UserPrincipal.Current.Guid.ToString();

    return isDomainJoined ? UserPrincipal.Current.Guid.ToString() : string.Empty;
}
catch (PrincipalServerDownException)
{
    Console.WriteLine("PrincipalServerDown Exception");
} 
catch (InvalidOperationException)
{
    Console.WriteLine("InvalidOperationException Exception");
}
catch (NoMatchingPrincipalException)
{
    Console.WriteLine("NoMatchingPrincipalException Exception");
}
catch (MultipleMatchesException)
{
    Console.WriteLine("MultipleMatchesException Exception");
}
catch (Exception e)
{
    Console.WriteLine("Exception Thrown : " + e);
    Console.WriteLine("Stack Trace : " + e.StackTrace);
}

And here is the pulled Guid and the exception:

User Guid Value after init: 30feXXX-XXXX-XXXX-XXXX-5fab5732f48a
Exception thrown: 'System.Runtime.InteropServices.COMException' in System.DirectoryServices.dll
Exception thrown: 'System.Runtime.InteropServices.COMException' in System.DirectoryServices.AccountManagement.dll
Exception Thrown : System.Runtime.InteropServices.COMException (0x8007200A): The specified directory service attribute or value does not exist.

   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_SchemaEntry()
   at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)
   at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options)
   at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry)
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
   at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)
   at System.DirectoryServices.AccountManagement.UserPrincipal.get_Current()
   at DomainJoinCheck.Program.GetCurrentUserGuid() in C:\VSC_Repositories\DomainJoinCheck2\DomainJoinCheck\Program.cs:line 31
Stack Trace :    at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_SchemaEntry()
   at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)
   at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options)
   at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry)
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
   at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)
   at System.DirectoryServices.AccountManagement.UserPrincipal.get_Current()
   at DomainJoinCheck.Program.GetCurrentUserGuid() in C:\VSC_Repositories\DomainJoinCheck2\DomainJoinCheck\Program.cs:line 31


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source