Getting access denied error when querying for user Roles using Authorization Role Manager

Recently I was working on an AuthorizationRoleProvider issue for an ASP.Net application. Customer was using Authorization Role Manager for the Role management of the Active Directory users.

Scenario
=======

You developed an Asp.net application using Authorization Role provider. We logged in as User1 into the application through Forms authentication. We used the following code:

string role="Admin";
if (Roles.IsUserInRole(“User2”,role))
{
//Do something
}

When we try to check if User2 is in role Admin we were getting the following error in the application:

Server Error in '/AzManTest' Application.
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
Exception Details: System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

Source Error:
Line 38: if (Roles.IsUserInRole(
Line 39: strUserName,
Line 40: role))

Stack Trace:

[UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))]
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters) +0
System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) +337
System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture) +36
System.Web.Security.AuthorizationStoreRoleProvider.CallMethod(Object objectToCallOn, String methodName, Object[] args) +183
System.Web.Security.AuthorizationStoreRoleProvider.GetClientContextFromName(String userName) +167
System.Web.Security.AuthorizationStoreRoleProvider.GetClientContext(String userName) +70
System.Web.Security.AuthorizationStoreRoleProvider.IsUserInRoleCore(String username, String roleName) +62
System.Web.Security.AuthorizationStoreRoleProvider.IsUserInRole(String username, String roleName) +93
System.Web.Security.Roles.IsUserInRole(String username, String roleName) +398
Login_Page.LoginCtrl_Authenticate(Object sender, AuthenticateEventArgs e) in e:\Inetpub\wwwroot\AzManTest\Login.aspx.cs:38
System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e) +108
System.Web.UI.WebControls.Login.AttemptLogin() +115
System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e) +101
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +166
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565

I opened the .net reflector and looked for the failing method AuthorizationStoreRoleProvider.GetClientContextFromName which is internally calling the Azman API method InitializeClientContextFromName.

private object GetClientContextFromName(string userName)
{
    string[] strArray = userName.Split(new char[] { '\\' });
    string str = null;
    if (strArray.Length > 1)
    {
        str = strArray[0];
        userName = strArray[1];
    }
    object[] args = new object[] { userName, str, null };
    return this.CallMethod(this._ObjAzApplication, "InitializeClientContextFromName", args);
}

We were able to reproduce this issue in our lab environment using the Microsoft.Interop.Security.AzRoles.dll assembly and were getting the same error.

Server Error in '/' Application.
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access is denied.
(Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
Source Error:
Line 31:
Line 32: clientContext =azApp.InitializeClientContextFromName("user2", "DM", null);

Cause and Resolution
================

We checked the documentation of this failing API method InitializeClientContextFromName in the following msdn article:

https://msdn.microsoft.com/en-us/library/aa377363(VS.85).aspx

Here is an excerpt from the above link:

“There are security requirements to call this API. The caller of the API must have READ permissions to the tokenGroupsGlobalAndUniversal attribute of the targeted user or the caller (USER) of the API should be part of the Pre-Windows 2000 compatible Access Group in the domain for this to succeed. The read access to the tokenGroupsGlobalAndUniversal attribute is granted to the Pre-Windows 2000 Compatible Access group, but new domains contain an empty Pre-Windows 2000 Compatible Access group by default because the default setup selection is Permissions compatible with Windows 2000 and Windows Server 2003”.

For example User1 is checking if User2 is part of any role then User1 should be part of the Pre-Windows 2000 compatible Access Group in the domain or must have READ permissions to the tokenGroupsGlobalAndUniversal attribute of the targeted user.

Useful articles
===========
InitializeClientContextFromName
https://msdn.microsoft.com/en-us/library/aa377363(VS.85).aspx

Some applications and APIs require access to authorization information on account objects
https://support.microsoft.com/kb/331951

Impersonation Shenanigans
https://blogs.msdn.com/azman/archive/2007/01/16/impersonation-shenanigans.aspx

Why cacheRolesinCookie does not work well with the Ajax Extensions 1.0 and RoleManager of .NET Framework 2.0?
https://blogs.msdn.com/webtopics/archive/2009/01/30/why-cacherolesincookie-does-not-work-well-with-the-ajax-extensions-1-0-and-rolemanager-of-net-framework-2-0.aspx