Important: Setting the Client Principal in ASP.NET Web API

Due to some unfortunate mechanisms buried deep in ASP.NET, setting Thread.CurrentPrincipal in Web API web hosting is not enough.

When hosting in ASP.NET, Thread.CurrentPrincipal might get overridden with HttpContext.Current.User when creating new threads. This means you have to set the principal on both the thread and the HTTP context. See here.

<rant>Oh well, can’t tell you how much I think that sucks. It is not the Web API guys fault – just a good example of why the design around HttpContext.User was completely flawed to start with.</rant>

This entry was posted in WebAPI. Bookmark the permalink.

7 Responses to Important: Setting the Client Principal in ASP.NET Web API

  1. Jose Luis says:

    Hi i have question here:

    http://stackoverflow.com/questions/11636605/webapi-iprincipal-and-authorize

    and i`ve tried your suggestion setting also in global asax both:

    var formsAuthentication = new FormsAuthenticationService();
    var ticket = formsAuthentication.Decrypt(authCookie.Value);
    var siteIdentity = new SiteIdentity(ticket);
    IPrincipal principal= new GenericPrincipal(siteIdentity, null);
    this.Context.User = principal;
    System.Threading.Thread.CurrentPrincipal = principal;

    but now i have an exception:

    Type is not resolved for member ‘Site.Web.Models.SiteIdentity,Site.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’

    and if i not use your suggestion as i explain on stackoverflow i was not able to use Principal for webapi

    Thanks for you suggestion in advance

    MVC4 and wepapi version from nuget package

    • I’d need at least the call stack to make any guess…

      • Jose Luis says:

        Thank you i post here:

        Type is not resolved for member ‘Site.Web.Models.SiteIdentity,Site.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’.

        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.Runtime.Serialization.SerializationException: Type is not resolved for member ‘Site.Web.Models.SiteIdentity,Site.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’.

        Source Error:

        An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

        Stack Trace:

        [SerializationException: Type is not resolved for member ‘Site.Web.Models.SiteIdentity,Site.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’.]
        Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0
        Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress() +65
        System.Web.HttpRequest.get_IsLocal() +23
        System.Web.Configuration.CustomErrorsSection.CustomErrorsEnabled(HttpRequest request) +86
        System.Web.HttpContextWrapper.get_IsCustomErrorEnabled() +45
        System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext) +72
        System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception) +115
        System.Web.Mvc.Async.c__DisplayClass25.b__22(IAsyncResult asyncResult) +105
        System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
        System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +45
        System.Web.Mvc.c__DisplayClass1d.b__18(IAsyncResult asyncResult) +14
        System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +25
        System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
        System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +61
        System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +25
        System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
        System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +49
        System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
        System.Web.Mvc.c__DisplayClassb.b__4(IAsyncResult asyncResult) +28
        System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +25
        System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
        System.Web.Mvc.c__DisplayClasse.b__d() +50
        System.Web.Mvc.SecurityUtil.b__0(Action f) +7
        System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
        System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
        System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
        System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8970061
        System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

        Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272

  2. Hard to tell. Sorry.

  3. Pingback: Using the JWT handler for Implementing “Poor Man”’s Delegation/ActAs - Vibro.NET - Site Home - MSDN Blogs

  4. Pingback: Using the JWT handler for Implementing “Poor Man”’s Delegation/ActAs | CloudIdentity

  5. Felix Antony says:

    thank you

Leave a comment