Preview 6 HTTPS Thread.CurrentPrincipal Problems [FIXED]

Topics: Web Api
Jan 30, 2012 at 6:27 PM
Edited Jan 30, 2012 at 6:28 PM

There appears to be a problem in Preview 6 with HTTPS support.

I have an operation handler used for authentication.  The handler sets the Thread.CurrentPrincipal to my own custom principal/identity objects.  With normal HTTP requests, I am able to get to my principal object just fine.

With HTTPS, WebApi seems to overwrite my principal object with a WindowsPrincipal/WindowsIdentity.  Can anyone else confirm this is a bug in WebApi?  I will continue with more testing before submitting an issue.

Jan 30, 2012 at 6:36 PM

Along with CurrentPrincipal, I've assigned the thread a unique name.  When the request enters the resource,  I can confirm it is the same thread being used, yet the CurrentPrincipal has been overwritten somewhere in the pipeline.

This does in fact seem to be a bug of some sort in WebApi.  Would be great to hear from others if they are encountering this as well.

Jan 30, 2012 at 9:24 PM

After extensive debugging, this doesn't seem to be a problem with WebApi.  The CurrentPrincipal is being overwritten in System.ServiceModel.dll

NOTE: I am hosting the WebApi services inside an MVC 3 project.  May this have something to do with it?

Here is the code I believe responsible for overwriting my principal.

System.ServiceModel.Dispatcher.SecurityImpersonationBehavior.SetCurrentThreadPrincipal(System.ServiceModel.ServiceSecurityContext securityContext, out bool isThreadPrincipalSet)

Viewing the call stack I can verify that this is the last call to set the CurrentPrincipal after my own.  Anyone have an idea as to this behavior?  Is there a configuration setting I may have missed?

    [MethodImpl(MethodImplOptions.NoInlining)]
    private IPrincipal SetCurrentThreadPrincipal(ServiceSecurityContext securityContext, out bool isThreadPrincipalSet)
    {
        IPrincipal currentPrincipal = null;
        IPrincipal windowsPrincipal = null;
        if (this.principalPermissionMode == PrincipalPermissionMode.UseWindowsGroups)
        {
            windowsPrincipal = this.GetWindowsPrincipal(securityContext);
        }
        else if (this.principalPermissionMode == PrincipalPermissionMode.UseAspNetRoles)
        {
            windowsPrincipal = new RoleProviderPrincipal(this.roleProvider, securityContext);
        }
        else if (this.principalPermissionMode == PrincipalPermissionMode.Custom)
        {
            windowsPrincipal = GetCustomPrincipal(securityContext);
        }
        if (windowsPrincipal != null)
        {
            currentPrincipal = Thread.CurrentPrincipal;
            Thread.CurrentPrincipal = windowsPrincipal;
            isThreadPrincipalSet = true;
            return currentPrincipal;
        }
        isThreadPrincipalSet = false;
        return currentPrincipal;
    }

Jan 30, 2012 at 9:32 PM

Just a little more digging and I found my answer.  I can now access my WebApi resources via HTTPS when they are hosted in an MVC project.

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

<behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceAuthorization principalPermissionMode="None"/>
        </behavior>
      </serviceBehaviors>
</behaviors>
Jan 30, 2012 at 10:06 PM

It could also be because you have a security mode set to forms or something.

Jan 31, 2012 at 4:03 AM

That might have something to do with it I suppose.  The odd thing is that this is not a problem on normal HTTP traffic.  Only becomes an issue with HTTPS.