We have a ASP.NET site that partially depends on forms authentication for login credentials, however the implementation of IPrincipal is completely custom.
But, when running the site on a particular server (which is somewhat semi-hardened when it comes to security), the app crashes when invoking IPrincipal.IsInRole() with the following messsage:
System.SystemException: The trust relationship between the primary domain and the trusted domain failed.
This indicates a communication error between the web-server and the DC, however since our application doesn't at all utilizes Windows authentication, I don't see why it needs to communicate with the DC.
This is my implementation:
[Serializable]
public class CustomPrincipal : IPrincipal
{
public CustomPrincipal( IUser userObj )
{
this.Identity = new CustomIdentity( userObj.Id, userObj.Username );
}
public bool IsInRole( string role )
{
if ( role == null )
return false;
var roles = HttpContext.Current.Session["authentication-roles"] as string[];
if (roles == null)
return false;
return Array.IndexOf( roles, role ) >= 0;
}
public IIdentity Identity { get; private set; }
public CustomIdentity FullIdentity
{
get { return (CustomIdentity) this.Identity; }
}
}
When debugging it locally (where it works) it is the correct implementation that is actually run. The usage is the following:
public override void Render()
{
var items = this.manager.Items
.Where( i => EngineContext.CurrentUser.IsInRole( i.Role.InternalName ) );
Setting a breakpoint here gives me that EngineContext.CurrentUser is actually the implementation of CustomPrincipal.
Has anyone experienced this? How is it possible that ASP.NET still seems to trigger any LDAP-lookups on an Interface method?
i found this, http://support.microsoft.com/kb/976494 but in my environment both the webs-server and the DC is 2008 R2 so this shouldn't apply. I do however have some errors in my event-log that indicates that there are some communication-issues with the DC, but since we don't rely on LDAP, that shouldn't be a problem.
The Security System could not establish a secured connection with the server ldap/ddc.domain.com/xxxxxxxxxxxxx. No authentication protocol was available.
The servers ore out of my scope which means I cannot fix this myself, I do however have a support-ticket for it, but it might be intentional to have this setup for security reasons (even though it seems dumb).
Has anyone experienced this issue?
Followup: the stack trace shows this:
at System.Security.Principal.NTAccount.TranslateToSids(IdentityReferenceCollection sourceAccounts, Boolean& someFailed)
at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)
at System.Security.Principal.WindowsPrincipal.IsInRole(String role)
at Company.Sites.Manager.ViewComponents.MenuComponent.<Render>b__0(INavigationItem i)
EDIT:
I was finally enable to reproduce this error on my dev-machine (i revoked my machine from the DC yesterday, but didn't reproduce it until today)
HttpContext.User is actually a WindowsPrincipal by default it seems, and the error in my code was that I only replace it with CustomPrincipal upon login. Hence, unathenticated users still get the WindowsPrincipal which then fails horribly if you have trust issues on your AD.
I tried changing the default principal by invoking this on appstart
AppDomain.CurrentDomain.SetPrincipalPolicy( PrincipalPolicy.NoPrincipal);
But this doesn't seem to kick in. How do I change the default Principal in ASP.NET?