views:

123

answers:

1

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?

A: 

I thought that it was the WindowsAuthenticationModule that added WindowsPrincipal to HttpContext.User, but removing that still gave the same issue. That was implied in this article:

http://msdn.microsoft.com/en-us/library/ff647076.aspx

I tried setting AppDomain.CurrentDomain.SetPrincipalPolicy( PrincipalPolicy.NoPrincipal);

on appstart and OnAuthenticateRequest as the suggested but to no avail.

However, this worked (in OnAuthenticateRequest):

Context.User = new GenericPrincipal(new GenericIdentity(String.Empty), new string[0]);

I will settle for this for now. Thanks for everyones input!

jishi
Global.asax OnAuthenticationRequest
onof