Setting Principle for HttpWorkerRequest

Discussion in 'ASP .Net Security' started by Michael Palmer, Aug 10, 2005.

  1. I am implementing my own web server that will authenticate users using out-of-band
    methods (like IIS does in the case of Windows authentication). I am implementing
    an HttpWorkerRequest and asking HttpRuntime to process the request. I expect
    existing ASP.NET applications to work without changes, but if those applications
    happen to examine HttpContext.Current.User.Identity or HttpContext.Principal,
    they should see the credentials that my code set in advance.

    Any ideas how I may do this? I've found similar threads but none have provided
    a solution.

    Thanks in advance,

    Michae
     
    Michael Palmer, Aug 10, 2005
    #1
    1. Advertising

  2. Michael Palmer

    Brock Allen Guest

    You should handle the HttpApplication's Authenticate event. This is how Windows
    and orms authentication modules are implemented. Is your user a Windows user?
    If so, then all you'd need to do is implement the WorkerRequests's GetToken()
    method. Here's how WindowsAuthModule does its magic (thie important line
    of code is the last one):

    WindowsIdentity identity1;
    string text1 = context1.WorkerRequest.GetServerVariable("LOGON_USER");
    string text2 = context1.WorkerRequest.GetServerVariable("AUTH_TYPE");
    if (text1 == null)
    {
    text1 = string.Empty;
    }
    if (text2 == null)
    {
    text2 = string.Empty;
    }
    if ((text1.Length == 0) && ((text2.Length == 0) || (string.Compare(text2,
    "basic", true, CultureInfo.InvariantCulture) == 0)))
    {
    identity1 = WindowsAuthenticationModule._anonymousIdentity;
    }
    else
    {
    identity1 = new WindowsIdentity(context1.WorkerRequest.GetUserToken(),
    text2, WindowsAccountType.Normal, true);
    }

    -Brock
    DevelopMentor
    http://staff.develop.com/ballen



    > I am implementing my own web server that will authenticate users using
    > out-of-band methods (like IIS does in the case of Windows
    > authentication). I am implementing an HttpWorkerRequest and asking
    > HttpRuntime to process the request. I expect existing ASP.NET
    > applications to work without changes, but if those applications happen
    > to examine HttpContext.Current.User.Identity or HttpContext.Principal,
    > they should see the credentials that my code set in advance.
    >
    > Any ideas how I may do this? I've found similar threads but none have
    > provided a solution.
    >
    > Thanks in advance,
    >
    > Michael
    >
     
    Brock Allen, Aug 10, 2005
    #2
    1. Advertising

  3. Hello Brock,

    Thanks for your reply. Forgive my ignorance, but I'm a Windows app guy trying
    to make better sense of the ASP.NET world. I've found some rather simple
    examples of hosting ASP.NET within a Windows forms app. My goal is to have
    a Windows form containing a WebBrowser control which will display the results
    of aspx files. I've gotten this far no problem. I'm now needing to display
    WebParts within these aspx pages, but it won't let me customize the WebParts
    at runtime because it personalizes WebParts for each connecting user. Running
    the ASP.NET within IIS or Cassini somehow allows HttpContext.Current.User.Identity
    to return the correctly connecting user and thus allow WebParts to personalize
    correctly. But, when asp.net runs within my own process HttpContext.Current.User.Identity
    shows up empty/null. I'm not sure how to get it to report the user under
    which the Windows forms app is running.

    Am I making any sense?

    -Michael

    > You should handle the HttpApplication's Authenticate event. This is
    > how Windows and orms authentication modules are implemented. Is your
    > user a Windows user? If so, then all you'd need to do is implement the
    > WorkerRequests's GetToken() method. Here's how WindowsAuthModule does
    > its magic (thie important line of code is the last one):
    >
    > WindowsIdentity identity1;
    > string text1 = context1.WorkerRequest.GetServerVariable("LOGON_USER");
    > string text2 = context1.WorkerRequest.GetServerVariable("AUTH_TYPE");
    > if (text1 == null)
    > {
    > text1 = string.Empty;
    > }
    > if (text2 == null)
    > {
    > text2 = string.Empty;
    > }
    > if ((text1.Length == 0) && ((text2.Length == 0) ||
    > (string.Compare(text2,
    > "basic", true, CultureInfo.InvariantCulture) == 0)))
    > {
    > identity1 = WindowsAuthenticationModule._anonymousIdentity;
    > }
    > else
    > {
    > identity1 = new
    > WindowsIdentity(context1.WorkerRequest.GetUserToken(),
    > text2, WindowsAccountType.Normal, true);
    > }
    >
    > -Brock
    > DevelopMentor
    > http://staff.develop.com/ballen
    >> I am implementing my own web server that will authenticate users
    >> using out-of-band methods (like IIS does in the case of Windows
    >> authentication). I am implementing an HttpWorkerRequest and asking
    >> HttpRuntime to process the request. I expect existing ASP.NET
    >> applications to work without changes, but if those applications
    >> happen to examine HttpContext.Current.User.Identity or
    >> HttpContext.Principal, they should see the credentials that my code
    >> set in advance.
    >>
    >> Any ideas how I may do this? I've found similar threads but none have
    >> provided a solution.
    >>
    >> Thanks in advance,
    >>
    >> Michael
    >>
     
    Michael Palmer, Aug 10, 2005
    #3
  4. Michael Palmer

    [MSFT] Guest

    [MSFT], Aug 11, 2005
    #4
  5. Hello Luke,

    Thanks for your reply, but that thread is a link back to this very conversation....
    Unless I'm not seeing what you do.

    > Hello Michael,
    >
    > You may take a look at this thread;
    >
    > http://groups.google.com/group/microsoft.public.dotnet.framework.aspne
    > t.secu
    > rity/browse_thread/thread/8f6a49774ca07427/28d39723f836f94c?lnk=st&q=H
    > ttpRun
    > time+and+(Identity+or+Principal)&rnum=1&hl=zh-CN#28d39723f836f94c
    >
    > It talks about same question.
    >
    > Hope this help,
    >
    > Luke
    >
     
    Michael Palmer, Aug 11, 2005
    #5
  6. Michael Palmer

    Brock Allen Guest

    So you're runing a WinForms app that loads a browser that connects to the
    same process that's also hosting ASP.NET? Just confirming...

    So who do you want the HttpContext.Current.User to be? If you want it to
    be the identity of the web server host process, then I think all you need
    to to is mark your app as using Windows authentication (in web.config) and
    then make the token available from your custom HttpWorkerRequest in GetUserToken().

    -Brock
    DevelopMentor
    http://staff.develop.com/ballen



    > Hello Brock,
    >
    > Thanks for your reply. Forgive my ignorance, but I'm a Windows app guy
    > trying to make better sense of the ASP.NET world. I've found some
    > rather simple examples of hosting ASP.NET within a Windows forms app.
    > My goal is to have a Windows form containing a WebBrowser control
    > which will display the results of aspx files. I've gotten this far no
    > problem. I'm now needing to display WebParts within these aspx pages,
    > but it won't let me customize the WebParts at runtime because it
    > personalizes WebParts for each connecting user. Running the ASP.NET
    > within IIS or Cassini somehow allows HttpContext.Current.User.Identity
    > to return the correctly connecting user and thus allow WebParts to
    > personalize correctly. But, when asp.net runs within my own process
    > HttpContext.Current.User.Identity shows up empty/null. I'm not sure
    > how to get it to report the user under which the Windows forms app is
    > running.
    >
    > Am I making any sense?
    >
    > -Michael
    >
    >> You should handle the HttpApplication's Authenticate event. This is
    >> how Windows and orms authentication modules are implemented. Is your
    >> user a Windows user? If so, then all you'd need to do is implement
    >> the WorkerRequests's GetToken() method. Here's how WindowsAuthModule
    >> does its magic (thie important line of code is the last one):
    >>
    >> WindowsIdentity identity1;
    >> string text1 =
    >> context1.WorkerRequest.GetServerVariable("LOGON_USER");
    >> string text2 = context1.WorkerRequest.GetServerVariable("AUTH_TYPE");
    >> if (text1 == null)
    >> {
    >> text1 = string.Empty;
    >> }
    >> if (text2 == null)
    >> {
    >> text2 = string.Empty;
    >> }
    >> if ((text1.Length == 0) && ((text2.Length == 0) ||
    >> (string.Compare(text2,
    >> "basic", true, CultureInfo.InvariantCulture) == 0)))
    >> {
    >> identity1 = WindowsAuthenticationModule._anonymousIdentity;
    >> }
    >> else
    >> {
    >> identity1 = new
    >> WindowsIdentity(context1.WorkerRequest.GetUserToken(),
    >> text2, WindowsAccountType.Normal, true);
    >> }
    >> -Brock
    >> DevelopMentor
    >> http://staff.develop.com/ballen
    >>> I am implementing my own web server that will authenticate users
    >>> using out-of-band methods (like IIS does in the case of Windows
    >>> authentication). I am implementing an HttpWorkerRequest and asking
    >>> HttpRuntime to process the request. I expect existing ASP.NET
    >>> applications to work without changes, but if those applications
    >>> happen to examine HttpContext.Current.User.Identity or
    >>> HttpContext.Principal, they should see the credentials that my code
    >>> set in advance.
    >>>
    >>> Any ideas how I may do this? I've found similar threads but none
    >>> have provided a solution.
    >>>
    >>> Thanks in advance,
    >>>
    >>> Michael
    >>>
     
    Brock Allen, Aug 11, 2005
    #6
  7. Michael Palmer

    [MSFT] Guest

    Hello Michael,

    Not sure why that link didn't work for you. I post the infomation from that
    thread here, you may take a look to see if it will help:

    Stephen Walch :

    I am implementing an ASP.NET server (similar to Cassini) and am trying to
    think through how I would go about adding my own authentication to (based
    on
    information I am able to extract from the raw HTTP request). It looks like
    my ultimate goal is to set HTTPContext.Principal with a principal that
    contains the appropriate identity, roles, etc.

    So if I have created an HttpWorkerRequest and am about to call
    HttpRuntime.ProcessRequest, what else do I need to do? I see that the
    HTTPContext takes HttpWorkerRequest in its constructor, so I deduce that
    the
    Principal is somehow created from the HttpWorkerRequest, but I can't figure
    out how.

    Any guidelines would be much appreciated. Thanks!

    Mike Moore [MSFT] :

    Hi,


    With off-line communication, we found this solution for Steve:


    1)
    Dim g As New System.Security.Principal.Gene-ricIdentity(...)
    HttpContext.Current.User = g


    2)
    Place the above in an HTTPModule so that it affects the entire application.
    For information on writing modules:
    308000 HOW TO: Create an ASP.NET HTTP Module Using Visual Basic .NET
    http://support.microsoft.com/?id=308000


    Thank you, Mike Moore
    Microsoft, ASP.NET


    This posting is provided "AS IS", with no warranties, and confers no
    rights.

    Frank :

    Hallo,


    why is the call(different Principals)


    System.Threading.Thread.Curren-tPrincipal


    different from the call
    Context.User


    I would like to use PrincipalPermission and User.IsinRole in a normal
    WebService Method. For that reason i have to set the
    Thread.CurrentPrincipal, but the User has another Principal, so i have set
    the user Context.User with the new GenericUser, too. Why?


    Frank


    "Bassel Tabbara [MSFT]" :

    Hello Frank,
    You need to create a HTTPModule that will handle the authentication there.
    HTTP modules and HTTP handlers are an integral part of the ASP.NET
    architecture. While a request is being processed, each request is processed
    by multiple HTTP modules (for example, the authentication module and the
    session module) and is then processed by a single HTTP handler. After the
    handler has processed the request, the request flows back through the HTTP
    modules.


    Modules are called before and after the handler executes. Modules enable
    developers to intercept, participate in, or modify each individual request.
    Modules implement the IHttpModule interface, which is located in the
    System.Web namespace.
    An HttpApplication class provides a number of events with which modules can
    synchronize. The following events are available for modules to synchronize
    with on each request. These events are listed in sequential order:


    - BeginRequest.
    - AuthenticateRequest
    - AuthorizeRequest
    - ResolveRequestCache
    - AcquireRequestState
    - PreRequestHandlerExecute
    - PostRequestHandlerExecute
    - ReleaseRequestState
    - UpdateRequestCache
    - EndRequest


    The following events are available for modules to synchronize with for each
    request transmission. The order of these events is non-deterministic.


    - PreSendRequestHeaders
    - PreSendRequestContent
    - Error


    For more information refer to the following Kb articles:


    307996 HOW TO: Create an ASP.NET HTTP Module Using Visual C# .NET
    http://support.microsoft.com/?id=307996


    308000 HOW TO: Create an ASP.NET HTTP Module Using Visual Basic .NET
    http://support.microsoft.com/?id=308000


    Thanks,
    Bassel Tabbara
    Microsoft, ASP.NET


    This posting is provided "AS IS", with no warranties, and confers no
    rights.

    "Bassel Tabbara [MSFT]" :

    Hello Frank,
    I am sorry for the last post.
    I am including below the right answer:


    Basically, Context.User is what ASP.Net uses. The HttpContext.User property
    provides programmatic access to the properties and methods of the
    IPrincipal interface. Because ASP.NET pages contain a default reference to
    the System.Web namespace (which contains the HttpContext class), you can
    reference the members of HttpContext on an .aspx page without the fully
    qualified class reference to HttpContext. For example, you can use just
    User.Identity.Name to get the name of the user on whose behalf the current
    process is running. It will return the authenticated user.


    System.Threading.Thread.Curren-tPrincipal is used as a local storage of the
    thread. It Gets or sets the thread's current principal (for role-based
    security).
    Without impersonation, this identity will be empty. Only in ASP.Net, it
    will be equal to Context.User. In normal windows apps this will return null
    value.
    You have to set it in your application, for example in a thread pool you
    will set the currentPrincipal to an identity for a particular thread.


    I hope this helps.


    Thanks,
    Bassel Tabbara
    Microsoft, ASP.NET


    This posting is provided "AS IS", with no warranties, and confers no
    rights.
     
    [MSFT], Aug 12, 2005
    #7
  8. That's perfect... thanks for the info. It works now!


    > Hello Michael,
    >
    > Not sure why that link didn't work for you. I post the infomation from
    > that thread here, you may take a look to see if it will help:
    >
    > Stephen Walch :
    >
    > I am implementing an ASP.NET server (similar to Cassini) and am trying
    > to think through how I would go about adding my own authentication to
    > (based on information I am able to extract from the raw HTTP request).
    > It looks like my ultimate goal is to set HTTPContext.Principal with a
    > principal that contains the appropriate identity, roles, etc.
    >
    > So if I have created an HttpWorkerRequest and am about to call
    > HttpRuntime.ProcessRequest, what else do I need to do? I see that the
    > HTTPContext takes HttpWorkerRequest in its constructor, so I deduce
    > that the Principal is somehow created from the HttpWorkerRequest, but
    > I can't figure out how.
    >
    > Any guidelines would be much appreciated. Thanks!
    >
    > Mike Moore [MSFT] :
    >
    > Hi,
    >
    > With off-line communication, we found this solution for Steve:
    >
    > 1)
    > Dim g As New System.Security.Principal.Gene-ricIdentity(...)
    > HttpContext.Current.User = g
    > 2) Place the above in an HTTPModule so that it affects the entire
    > application. For information on writing modules: 308000 HOW TO: Create
    > an ASP.NET HTTP Module Using Visual Basic .NET
    > http://support.microsoft.com/?id=308000
    >
    > Thank you, Mike Moore Microsoft, ASP.NET
    >
    > This posting is provided "AS IS", with no warranties, and confers no
    > rights.
    >
    > Frank :
    >
    > Hallo,
    >
    > why is the call(different Principals)
    >
    > System.Threading.Thread.Curren-tPrincipal
    >
    > different from the call Context.User
    >
    > I would like to use PrincipalPermission and User.IsinRole in a normal
    > WebService Method. For that reason i have to set the
    > Thread.CurrentPrincipal, but the User has another Principal, so i have
    > set the user Context.User with the new GenericUser, too. Why?
    >
    > Frank
    >
    > "Bassel Tabbara [MSFT]" :
    >
    > Hello Frank, You need to create a HTTPModule that will handle the
    > authentication there. HTTP modules and HTTP handlers are an integral
    > part of the ASP.NET architecture. While a request is being processed,
    > each request is processed by multiple HTTP modules (for example, the
    > authentication module and the session module) and is then processed by
    > a single HTTP handler. After the handler has processed the request,
    > the request flows back through the HTTP modules.
    >
    > Modules are called before and after the handler executes. Modules
    > enable developers to intercept, participate in, or modify each
    > individual request. Modules implement the IHttpModule interface, which
    > is located in the System.Web namespace. An HttpApplication class
    > provides a number of events with which modules can synchronize. The
    > following events are available for modules to synchronize with on each
    > request. These events are listed in sequential order:
    >
    > - BeginRequest. - AuthenticateRequest - AuthorizeRequest -
    > ResolveRequestCache - AcquireRequestState - PreRequestHandlerExecute -
    > PostRequestHandlerExecute - ReleaseRequestState - UpdateRequestCache -
    > EndRequest
    >
    > The following events are available for modules to synchronize with for
    > each request transmission. The order of these events is
    > non-deterministic.
    >
    > - PreSendRequestHeaders - PreSendRequestContent - Error
    >
    > For more information refer to the following Kb articles:
    >
    > 307996 HOW TO: Create an ASP.NET HTTP Module Using Visual C# .NET
    > http://support.microsoft.com/?id=307996
    >
    > 308000 HOW TO: Create an ASP.NET HTTP Module Using Visual Basic .NET
    > http://support.microsoft.com/?id=308000
    >
    > Thanks, Bassel Tabbara Microsoft, ASP.NET
    >
    > This posting is provided "AS IS", with no warranties, and confers no
    > rights.
    >
    > "Bassel Tabbara [MSFT]" :
    >
    > Hello Frank, I am sorry for the last post. I am including below the
    > right answer:
    >
    > Basically, Context.User is what ASP.Net uses. The HttpContext.User
    > property provides programmatic access to the properties and methods of
    > the IPrincipal interface. Because ASP.NET pages contain a default
    > reference to the System.Web namespace (which contains the HttpContext
    > class), you can reference the members of HttpContext on an .aspx page
    > without the fully qualified class reference to HttpContext. For
    > example, you can use just User.Identity.Name to get the name of the
    > user on whose behalf the current process is running. It will return
    > the authenticated user.
    >
    > System.Threading.Thread.Curren-tPrincipal is used as a local storage
    > of the thread. It Gets or sets the thread's current principal (for
    > role-based security). Without impersonation, this identity will be
    > empty. Only in ASP.Net, it will be equal to Context.User. In normal
    > windows apps this will return null value. You have to set it in your
    > application, for example in a thread pool you will set the
    > currentPrincipal to an identity for a particular thread.
    >
    > I hope this helps.
    >
    > Thanks, Bassel Tabbara Microsoft, ASP.NET
    >
    > This posting is provided "AS IS", with no warranties, and confers no
    > rights.
    >
     
    Michael Palmer, Aug 12, 2005
    #8
  9. Hello Brock,

    Thanks for your reply. I think I got it figured out thanks to you and others
    in this thread. Thank you again for your help.

    -Michael


    > So you're runing a WinForms app that loads a browser that connects to
    > the same process that's also hosting ASP.NET? Just confirming...
    >
    > So who do you want the HttpContext.Current.User to be? If you want it
    > to be the identity of the web server host process, then I think all
    > you need to to is mark your app as using Windows authentication (in
    > web.config) and then make the token available from your custom
    > HttpWorkerRequest in GetUserToken().
    >
    > -Brock
    > DevelopMentor
    > http://staff.develop.com/ballen
    >> Hello Brock,
    >>
    >> Thanks for your reply. Forgive my ignorance, but I'm a Windows app
    >> guy trying to make better sense of the ASP.NET world. I've found some
    >> rather simple examples of hosting ASP.NET within a Windows forms app.
    >> My goal is to have a Windows form containing a WebBrowser control
    >> which will display the results of aspx files. I've gotten this far no
    >> problem. I'm now needing to display WebParts within these aspx pages,
    >> but it won't let me customize the WebParts at runtime because it
    >> personalizes WebParts for each connecting user. Running the ASP.NET
    >> within IIS or Cassini somehow allows
    >> HttpContext.Current.User.Identity to return the correctly connecting
    >> user and thus allow WebParts to personalize correctly. But, when
    >> asp.net runs within my own process HttpContext.Current.User.Identity
    >> shows up empty/null. I'm not sure how to get it to report the user
    >> under which the Windows forms app is running.
    >>
    >> Am I making any sense?
    >>
    >> -Michael
    >>
    >>> You should handle the HttpApplication's Authenticate event. This is
    >>> how Windows and orms authentication modules are implemented. Is your
    >>> user a Windows user? If so, then all you'd need to do is implement
    >>> the WorkerRequests's GetToken() method. Here's how WindowsAuthModule
    >>> does its magic (thie important line of code is the last one):
    >>>
    >>> WindowsIdentity identity1;
    >>> string text1 =
    >>> context1.WorkerRequest.GetServerVariable("LOGON_USER");
    >>> string text2 =
    >>> context1.WorkerRequest.GetServerVariable("AUTH_TYPE");
    >>> if (text1 == null)
    >>> {
    >>> text1 = string.Empty;
    >>> }
    >>> if (text2 == null)
    >>> {
    >>> text2 = string.Empty;
    >>> }
    >>> if ((text1.Length == 0) && ((text2.Length == 0) ||
    >>> (string.Compare(text2,
    >>> "basic", true, CultureInfo.InvariantCulture) == 0)))
    >>> {
    >>> identity1 = WindowsAuthenticationModule._anonymousIdentity;
    >>> }
    >>> else
    >>> {
    >>> identity1 = new
    >>> WindowsIdentity(context1.WorkerRequest.GetUserToken(),
    >>> text2, WindowsAccountType.Normal, true);
    >>> }
    >>> -Brock
    >>> DevelopMentor
    >>> http://staff.develop.com/ballen
    >>>> I am implementing my own web server that will authenticate users
    >>>> using out-of-band methods (like IIS does in the case of Windows
    >>>> authentication). I am implementing an HttpWorkerRequest and asking
    >>>> HttpRuntime to process the request. I expect existing ASP.NET
    >>>> applications to work without changes, but if those applications
    >>>> happen to examine HttpContext.Current.User.Identity or
    >>>> HttpContext.Principal, they should see the credentials that my code
    >>>> set in advance.
    >>>>
    >>>> Any ideas how I may do this? I've found similar threads but none
    >>>> have provided a solution.
    >>>>
    >>>> Thanks in advance,
    >>>>
    >>>> Michael
    >>>>
     
    Michael Palmer, Aug 12, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bjorn
    Replies:
    1
    Views:
    646
    Alvin Bruney [MVP]
    Mar 4, 2004
  2. Bjorn
    Replies:
    2
    Views:
    554
    Bjorn
    Mar 4, 2004
  3. Replies:
    2
    Views:
    1,724
  4. Replies:
    0
    Views:
    390
  5. Norman Rasmussen

    Setting Principal for HttpWorkerRequest

    Norman Rasmussen, Dec 17, 2003, in forum: ASP .Net Security
    Replies:
    1
    Views:
    231
    Norman Rasmussen
    Dec 17, 2003
Loading...

Share This Page