locked
Writing my own value for cs-username RRS feed

  • Question

  • User1254222884 posted

    Can advanced logging allow me to write my own, arbitrary, changing value to the cs-username field in the logfile?  If so, can someone point me to the documentation for how to do this?

    TIA,

    Thursday, April 14, 2011 12:00 PM

All replies

  • User-1853252149 posted

     No, you'd need to write your own logging application most likely to handle this.  How about telling us what you want and we may be able to suggest a different method.

    Jeff

    Thursday, April 14, 2011 1:02 PM
  • User1254222884 posted

     No, you'd need to write your own logging application most likely to handle this.  How about telling us what you want and we may be able to suggest a different method.

    Jeff

    OK. We've written our own login system (since one didn't exist that worked until .net 3.0) that accesses our LEGACY (back to LDAP) user information database. What we have now is an ISAPI filter that intercepts the logfile write and substitutes in the username from our login system so that cs-user has that value (NOT a Windows or Network username).  So, I'd like to get that same functionality in a managed environment... Possible?  If not, I think we can still use the ISAPI (written with VS 2005, C++ MFC).

    Thanks,

    Thursday, April 14, 2011 1:38 PM
  • User-248641251 posted

    Owen,

    Have you found an answer yet?

    I’m in the same boat, cannot find any docs or code samples at all.

    Basically the question is:

    How do we get same functionality with IHttpModule/CHttpModule (managed or native module)

    public void Application_LogRequest( object source, EventArgs e )<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    available with ISAPI filter function:

    DWORD OnLog( const PHTTP_FILTER_CONTEXT pFC, const PHTTP_FILTER_LOG pLog)<o:p></o:p>

    It feels as there is a taboo on this sort of questions...

    <o:p> </o:p>
    Sunday, July 24, 2011 11:50 PM
  • User1254222884 posted

    Yes.  I am able to do this in IIS7, Integrated Mode Application Pool. I think it also requires dot-net 4.0 (we've not deployed this to production yet because we're not up to 4.0 on production yet)....

    In the AuthenticateRequest event of the Application object in an httpModule, do something like this:

          Private Sub Application_AuthenticateRequest(sender As Object, e As System.EventArgsHandles Application.AuthenticateRequest
             Dim objContext As HttpContext = HttpContext.Current
             If Not (objContext.Request.Cookies("SOMECOOKIE"Is NothingThen
                Dim strUser As String = HttpContext.Current.Request.Cookies("SOMECOOKIE").Value.ToString
                HttpContext.Current.User = New GenericPrincipal(New GenericIdentity(strUser), Nothing)
             End If
     
          End Sub
     

    This code grabs a value out of a cookie and sets that value as the value that is written to the log-file for the user-name. Hope this helps.... I lost a lot of hair over this one....

    Monday, July 25, 2011 10:47 AM
  • User-248641251 posted

    Owen,

    Wow - really great idea!

    Could you clarify, when you change

    HttpContext.Current.User = New GenericPrincipal(New GenericIdentity(strUser), Nothing)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    It does in fact change the request Principal(Identity), doesn’t it?

    We do have application pool identity is set to a domain user and use trusted database connections.

    IMO, if we change HttpContext.Current.User, in order to access protected resources, app code need to do another impersonation.

    Am I mistaken about it?

    <o:p> </o:p>

    BTW: It’s gotta be another way of doing it, see my comment about IIS URL Rewrite 2.0

    http://forums.iis.net/t/1180178.aspx

    Monday, July 25, 2011 1:10 PM
  • User1254222884 posted

    Not sure. We're using explicit connection strings to our database and not using any Windows identities explicitly.  Not sure exactly what ramifications there are to using New GenericPrincipal -- However, the user we're setting to does not exist anywhere on they server or network: it's an ID that we generated outside the scope of O/S users.  Doesn't seem to be affecting anything, but I'll do more testing in that regard before we attempt to go live with it.  You might try connecting to the db after doing the new principal thing... Not sure if HttpContext.Current.User is the same as the application pool identity...

    Good luck.

    Monday, July 25, 2011 2:09 PM
  • User-248641251 posted

    Owen,

    >Not sure if HttpContext.Current.User is the same as the application pool identity...<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    It’s not. IMO, the whole point of Authentication is to impersonate into another identity and use it to access resources.

    <o:p> </o:p>>You might try connecting to the db after doing the new principal thing...<o:p></o:p>

    Yep, I’m working on it right now. Or we can try to write a file into folder with read-write access to everyone and check the file owner after.

    Using explicit user/pwd to connect to DB will work just fine.

    Our application relies on trusted access everywhere. L

    Monday, July 25, 2011 3:40 PM
  • User-248641251 posted
    Did a test... A StreamWriter( log ) file is always owned by WindowsIdentity.GetCurrent( )<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    No matter how HttpContext.Current.User is set.

    using( StreamWriter sw = new StreamWriter( log ) ) {<o:p></o:p>      sw.WriteLine( HttpContext.Current.User == null ? "null" : HttpContext.Current.User.Identity.Name );<o:p></o:p>      sw.WriteLine( WindowsIdentity.GetCurrent( ).Name );<o:p></o:p>}<o:p></o:p><o:p> </o:p><o:p> </o:p>

    Could somebody explain following statement, please?

    http://msdn.microsoft.com/en-us/library/system.web.httpcontext.user.aspx#Y645

    For example, you can use User.Identity.Name to get the name of the user on whose behalf the current process is running.<o:p></o:p>
    Monday, July 25, 2011 5:07 PM
  • User-928856441 posted

    While this is a pretty old thread, it is directly on topic for me, and I know I can tell you what I want.

    I want to be able to log the user in place "at the end of the pipeline" instead of the user put in place during AuthenticateRequest phase. My example is so easy to see, I cannot figure out why no one else has ever asked for this. This example just serves to highlight a common way the problem exists, but it is not the only example our applications struggle with, it is just the easiest to detail here.

    Most sites (all not using some sort of Federated Authentication) that require Authentication to access some of the content employ a Log In screen of some kind. This screen necessarily must allow anonymous access, and so there always an anonymous User set into place during the AuthenticateRequest phase. But, by the time a successful login has been achieved by the Log In page, Context.User is "normally" set to the appropriate application provided IPrincipal/IIdentity, and once that has taken place, THAT is the user name that should be logged for those requests.

    I want to change the logged user name to the current IPrincipal/IIdentity in place and the end of the request, but it is captured and stored away somewhere just after the AuthenticateRequest phase, and these does not seem to be anything one can do to change it.

    Obviously I can add my own AuthenticateRequest handler, and do some fancy PEEKing into the post to see if it is a Log In request, but, while I have proven that will work, it is wrong because then it has to be able to do all the work of the Log In screen to find and validate the post.

    We have a version of this problem in a variety of sites and technologies (SOAP web service, MVC REST service, asp.Net website, ...), but the one thing that is true for each of them, by the end of the call that is currently a "-" where I want a user name, the Context.User has been set to an application IPrincipal/IIdentity instance whose .Name I want to appear in the IIS Advanced Logging Logs.

    I also realize I can added it as a custom header and log it that way, but then I have it logged twice for all the other Authenticated requests.

    Why does the guts of the IIS pipeline runner grab this data so early in the pipeline? How can I change it later in the pipeline? I am even willing to consider a reflection hack if it is reasonably possible, but I have yet to find the exact right thing to poke my value into.

    I hope this topic is still monitored and that someone might consider a reply.

    I guess I am looking for a Managed C# way to do this: http://msdn.microsoft.com/en-us/library/ms690742%28VS.90%29.aspx

    Sunday, January 18, 2015 7:55 AM