Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User.IsInRole("fake group") results in "The trust relationship between the primary domain and the trusted domain failed"

I have an MVC 3 app, using Windows Authentication with Claims using WIF 4.5.

Access to the application is controlled (currently) via membership in an AD group:

<deny users="?" />
<allow roles="domain\somegroup" />
<deny users="*" />

In addition to the AD groups, we have custom roles that need to be added. (This app is being converted from Forms to Windows authentication)

To support these custom roles (until they are managed in AD), we are adding them as ClaimTypes.GroupSid claims to the user, so that existing code utilizing [Authorize("ADMIN")] and User.IsInRole("ADMIN") continues to function:

Application_PostAuthenticateRequest(object sender, EventArgs e)
{
    var identity = ClaimsPrincipal.Current.Identity as WindowsIdentity;
    var roles = userDAL.GetRoles(identity.Name);
    foreach(var role in roles)
    {
        identity.AddClaim(new Claim(ClaimTypes.GroupSid, role));
    }
}

And this is all working as expected.

Except when the current user is NOT a member of some custom role (like ADMIN) and that role also doesn't exist in AD

We use [Authorize("ADMIN")] on Controller Action Methods, as well as various instances of User.IsInRole("ADMIN") depending in the scenario. It's in those instances where the error occurs and the app blows up.

The AD infrastructure is in the midst of an upgrade/migration. I'm not privy to all the details there, but I do know there are a handful of domains, supposedly with trust between them, and it's been alluded to me by the infrastructure folks that these trust relationships are up and running.

So really I guess I'm wondering 2 things:

  1. This really doesn't seem like something our code should have to handle. So what could really be wrong with the domain? Can I find out what 'trusted' domain the trust relationship is failing for?

  2. What is the best way to work around this? I dislike the idea of writing helper methods & Authorize() subclasses just to trap this exception.

like image 266
JoeBrockhaus Avatar asked Mar 19 '14 21:03

JoeBrockhaus


1 Answers

Please go to inetmgr, sites, default web site, site name, iis group, double-click authentication, disable anonymous authentication, then reset the app pool.

This appears to happen when windows cannot decipher the roles defined under the 'authorization, allow roles' tag in the web.config file. For testing comment out the custom roles tags from the web.config file. The issue appears to be caused when mixing up Forms authentication and Windows authentication. The magic happens in the Global.asax file Application_PostAuthenticateRequest method, when using Forms authentication you can Cast the User.Identity as FormsIdentity, then create the custom identity from the FormsIdentity Ticket, then create the custom principle from the custom identity, you will then be able to attach the CustomPrincipal to the Current User and Current Principal, ie.

Dim fIdent As FormsIdentity = CType(User.Identity, FormsIdentity)
Dim ci As New CustomIdentity(fIdent.Ticket) 
Dim cp As New CustomPrincipal(ci)
HttpContext.Current.User = cp : Thread.CurrentPrincipal = cp

For IIS you want to enable Forms authentication and anonymous authentication, everything else should be disabled. When using Windows authentication the Global.asax file Application_PostAuthenticateRequest method can create the custom principle directly from the User.Identity ie.

Dim cp As New CustomPrincipal(User.Identity)
HttpContext.Current.User = cp : Thread.CurrentPrincipal = cp

In this case the IIS settings should be Windows authentication and ASP.Net Impersonation is enabled and everything else is disabled.

Getting these authentication methods mixed up results in the 'The trust relationship between the primary domain and the trusted domain failed' error because if your Application_PostAuthenticateRequest method is not implementing the CustomPrinciple for some reason then windows will try to use the built in IsInRole function that checks the role against the domain roles instead of using your custom IsInRole that is in your CustomPrinciple code behind file.

Here is a useful article and links:

http://www.codeproject.com/Articles/8819/Authorize-and-authenticate-users-with-AD https://msdn.microsoft.com/en-us/library/ff647405.aspx
https://support.microsoft.com/en-us/kb/306359

like image 105
Roger Perkins Avatar answered Nov 18 '22 14:11

Roger Perkins