You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cli-users@httpd.apache.org by "William A. Rowe, Jr." <wr...@rowe-clan.net> on 2005/03/03 07:51:13 UTC

Re: [cli-users] mod_aspdotnet does not pass AUTH_TYPE or REMOTE_USER value?

Kishore's had an auth issue this week, but my theory on that bug
is that it's the custom error response used to force the redirect 
to the login page.

Your issue is with NTLM auth.  If you don't attempt to use system
credentials, all should work better.  There is an ntlm module,
but it isn't part of the core, and isn't integrated into mod_aspdotnet.


At 10:33 PM 3/2/2005, Walter Nicholls wrote:
>I'm becoming fairly sure that there is a problem with mod_aspdotnet not
>passing authentication information on to the ASP.NET framework.
>
>[This may be duplicate post to the list, I sent the first before my subscription was fully confirmed]
>
>Bugzilla appears to be down, so I haven't managed to research anything
>there.  My apologies for this being a bit wordy, I'm going to prove
>there is is something wrong and pinpoint it in this email if I can.
>
>The end result is that on a web application for which authentication is
>REQUIRED, the User.Identity... properties are set correctly under IIS,
>but not under Apache/mod_aspdotnet.  Since I have an application which
>is relying on these values, I cannot use mod_aspdotnet.  This pretty
>much eliminates Apache too, since Mono isn't an option with the code in
>the shape it is now.
>
>OK so I am using Windows XP SP2, Apache 2.0.53, and
>mod_aspdotnet-2.0.0.msi dated 21-Nov-2004. All current as of today.
>
>Some things which are working
>1. It all works OK under IIS ( obviously if it didn't I'd be looking for
>bugs in my code)
>2. Authentication is definitely occuring.  In IIS I have anonymous
>access disabled; under Apache AuthType Basic / AuthUserFile / Require
>... set ok.  Going straight in with a browser brings up login dialog,
>with WGET or the client app and no sensible credentials gives 401 error.
>3. ASP.NET code which does not look at the User.Identity  is also
>working fine.  Well, I haven't gone past anything but very basic things,
>but I can bring an .ASPX page in the browser and server-side code is
>running; I  can browse web service methods and test directly from
>Firefox, including getting complex results.  "This is cool", I think
>
>However then the differences occur
>Under IIS:
>  User.Identity.IsAuthenticated = true, IIS
>User.Identity.AuthenticationType = NTLM, and User.Identity.Name = (me)
>
>Under Apache
>  User.Identity.IsAuthenticated = false, IIS
>User.Identity.AuthenticationType = (empty string), and
>User.Identity.Name = (empty string)
>
>Expected - IsAuthenticated=true, AuthenticationType = Basic, Name = (me)
>(note the only difference being IIS will be NTLM, Apache Basic, and the
>user name in question, that's a genuine configuration difference. I'm
>not trying mod_auth_ntlm, yet)
>
>Digging further, and using the following code
>       private void Page_Load(object sender, System.EventArgs e)
>       {
>           // Put user code to initialize the page here
>           System.Text.StringBuilder sb = new System.Text.StringBuilder();
>           sb.Append( @"<h2>Server variables</h2><table>" );
>           for( int ii = 0; ii < Request.ServerVariables.Count; ++ii )
>           {
>               sb.AppendFormat( @"<tr><td>{0}</td><td>{1}</td></tr>",
>                       Request.ServerVariables.GetKey(ii),
>Request.ServerVariables[ii] );
>           }
>           sb.Append( @"</table>" );
>           Label1.Text = sb.ToString();
>       }
>
>This gives the following result under IIS (edited, I'm not showing the
>whole dump!):
>AUTH_TYPE    NTLM
>AUTH_USER    LAPUTA\Walter
>AUTH_PASSWORD
>LOGON_USER    laputa\Walter
>REMOTE_USER    LAPUTA\Walter
>
>Also, just
>REMOTE_ADDR    127.0.0.1
>REMOTE_HOST    127.0.0.1
>REQUEST_METHOD    GET
>SERVER_NAME    localhost
>SERVER_PORT    80
>SERVER_PROTOCOL    HTTP/1.1
>SERVER_SOFTWARE    Microsoft-IIS/5.1
>
>However under Apache I get: (same edited list)
>AUTH_TYPE
>AUTH_USER
>AUTH_PASSWORD
>LOGON_USER
>REMOTE_USER
>
>All the other variables have values as expected  (SERVER_NAME =
>localhost, SERVER_PORT = 80 or 81, SERVER_SOFTWARE = Microsoft-IIS/5.1
>or Apache/2.0.53 (Win32)).  Everything seems hunky-dory EXCEPT that
>under mod_aspdotnet all the user variables are blank, despite the fact
>that I'm logged in. So is it Apache or mod_aspdotnet?
>
>If I write a one line batch file consisting solely of the one line SET
>then the variables printed out are:
>REMOTE_USER=Walter
>AUTH_TYPE=Basic
>
>Which is conforming perfectly to the CGI 1.1 specification! So it would
>appear to be mod_aspdotnet which is at fault.
>
>Now I get a bit unsure of my ground. I assume the ASP.NET framework is
>using the GetServerVariable() method of the WorkerRequest object, and I
>can't see why this code doesn't return the same headers as Apache is
>supplying to the CGI file:
>       virtual String* GetServerVariable(String *name)
>       {
>           int ent = env_var->IndexOf(name);
>           if (ent >= 0) {
>               return static_cast<String*>(env_value->get_Item(ent));
>           }
>
>Are the REMOTE_USER and AUTH_TYPE environment variables manufactured by
>the Apache CGI handler?  In which case explicit tests like this might be
>warranted
>
> if ( name->Equals(L"REMOTE_USER") ) { return
>..whereever_you_get_this_from(); }
>
>It would also be very sane to implement AUTH_USER as an alias to
>REMOTE_USER as well, as an "IIS emulation", even though this is not part
>of the CGI specification there will be .NET applications which expect it.
>
>I'm completely out of my depth here, I don't know the first thing about
>the Apache API and patching and compiling, even some rudimentary tests.
>I'm only guessing that setting the REMOTE_USER and  AUTH_TYPE (and
>probably AUTH_USER) will fix the User.Identity problem.
>
>TIA for any help.  Patching the code and issuing a new release would be
>good <gd&r>
>
>Walter Nicholls
>Cornerstone Software Ltd
>
>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
>For additional commands, e-mail: cli-users-help@httpd.apache.org
>



---------------------------------------------------------------------
To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
For additional commands, e-mail: cli-users-help@httpd.apache.org


Re: [cli-users] mod_aspdotnet does not pass authentication info on to ASP.NET

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 08:45 PM 3/3/2005, Walter Nicholls wrote:
>zip attachment can be found at http://www.cornerstone.co.nz/temp/aspnetbug.zip
>
>Note in hindsight printvars.c is not actually required now I found that GetServerVariables is working correctly.

You see, the environment table is not actually part of the ASP.NET
specification.  GetServerVariables is where it's at.

Bill



---------------------------------------------------------------------
To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
For additional commands, e-mail: cli-users-help@httpd.apache.org


Re: [cli-users] mod_aspdotnet does not pass authentication info on to ASP.NET

Posted by Walter Nicholls <wa...@cornerstone.co.nz>.
zip attachment can be found at 
http://www.cornerstone.co.nz/temp/aspnetbug.zip

Note in hindsight printvars.c is not actually required now I found that 
GetServerVariables is working correctly.

Or alternatively:

=== aspnetbug.conf
usual mod_aspdotnet stuff plus

AspNetMount /aspnetbug "C:/temp/aspnetbug"
Alias /aspnetbug "C:/temp/aspnetbug"

# Enable scripts to be executed in this directory
<Directory "C:/temp/aspnetbug">
    Options FollowSymlinks ExecCGI
    Order allow,deny
    Allow from all

    # enable printvars.exe to run
    AddHandler cgi-script .exe

    # Require authentication
    AuthType basic
    AuthName "Test mod_aspdotnet bug"
    AuthUserFile "conf/bugusers"
    Require user test
  
</Directory>

=== bugusers
test:$apr1$JW4.....$bb.7.q9roAcdOmDgh2OyK.

=== printvars.aspx
<%@ Page Language="C#" %>
<html>
<body>

<h2>Results of reading (IIS/Apache) Server Variables</h2>
<p>Left column is in the ASP.NET Request.ServerVariables[] collection</p>
<p>Right column is what the WorkerRequest.GetServerVariable() method 
returns</p>
<p>Spot the difference!</p>

<%
// Get direct access to the server variables via the Workerrequest object.
IServiceProvider provider = (IServiceProvider) HttpContext.Current;
HttpRequest util = (HttpRequest) provider.GetService(typeof(HttpRequest));
HttpWorkerRequest wr = (HttpWorkerRequest) 
provider.GetService(typeof(HttpWorkerRequest));

// And print the variables from the two sources

Response.Write( "<table cellpadding=\"2px\">\n" );
Response.Write( "<tr><td>Variable</td><td>ServerVariables[x]<br 
/>collection</td><td>GetServerVariables(x)<br />method</td></tr>" );
Response.Write( String.Format(
    "<tr><td>AUTH_TYPE</td><td>{0}</td><td>{1}</td></tr>\n",
    Request.ServerVariables["AUTH_TYPE"], 
wr.GetServerVariable("AUTH_TYPE") ) );
Response.Write( String.Format(
    "<tr><td>AUTH_USER</td><td>{0}</td><td>{1}</td></tr>\n",
    Request.ServerVariables["AUTH_USER"], 
wr.GetServerVariable("AUTH_USER") ) );
Response.Write( String.Format(
    "<tr><td>REMOTE_USER</td><td>{0}</td><td>{1}</td></tr>\n",
    Request.ServerVariables["REMOTE_USER"], 
wr.GetServerVariable("REMOTE_USER") ) );
Response.Write( String.Format(
    "<tr><td>SERVER_SOFTWARE</td><td>{0}</td><td>{1}</td></tr>\n",
    Request.ServerVariables["SERVER_SOFTWARE"], 
wr.GetServerVariable("SERVER_SOFTWARE") ) );
Response.Write( "</table>\n" );
%>

</body>
</html>

=== printvars.c

#include <ctype.h>
#include <stdio.h>
#include <string.h>

char * interesting_vars[] =
{
    "AUTH_TYPE", "AUTH_USER", "REMOTE_USER", "SERVER_SOFTWARE", NULL
};
   

int main(int argc, char **argv, char **arge )
{
    char **pEnv, **pTest, *p; size_t len;
    printf( "Status: 200 OK\n" );
    printf( "Content-type: text/plain\n" );
    printf( "\n");
   
    for( pEnv = arge; NULL != *pEnv; ++pEnv )
    {
        // does it match one of the interesting ones?
        for( p= *pEnv; *p!='\0'&&*p!='='; ++p ) { } // find = or null
        while( p>*pEnv && isspace(*(p-1)) ) { --p; } // skip whitespace
        for( pTest = interesting_vars; NULL!=*pTest; ++pTest )
        {
            len = (size_t)(p-*pEnv);
            if( strlen(*pTest)==len && 0==strnicmp(*pEnv,*pTest,len) )
            {
                printf( "%s\n", *pEnv );
                break;//for
            }
        }
    }

    return 0;
}

---------------------------------------------------------------------
To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
For additional commands, e-mail: cli-users-help@httpd.apache.org


Re: [cli-users] mod_aspdotnet does not pass authentication info on to ASP.NET

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
OK - somewhere we are missing a linkage.  Should be a trivial
fix, but I have far fewer hours to spend on .NET than likely you
do, Walter.  Hopefully someone else on this list has the humor
to overlook your ostentatiousness.

I assure you, however, that no one will invest any effort 
in solving the legitimate issues you raise, when your thorough
reproduction case wasn't attached.

Did you forget to click attach?

</sarcasm>

There are EBCADs everywhere.  That includes aspdotnet.  If you
want us to work with you, we are glad to investigate what's 
going on.  If you don't have the time, don't bother with the 
report, we don't either.

mod_aspdotnet is free software.  Unlike MS - when it breaks,
you get to keep both pieces and fix them yourself if you like,
or work with the community to resolve the issues.

2.0 isn't even five months old, lighten up :)  There are even
snapshot builds of the most recent code at
http://httpd.apache.org/dev/dist/ if you care to ensure this
problem exists in the next coming release.

Bill


At 08:21 PM 3/3/2005, Walter Nicholls wrote:
>OK, I've wasted way too much time on this but I've eliminated two red herrings, IIS and the GetServerVariables() method
>
>Here's a repro:
>
>Attached zip file contains:
>   aspnetbug.conf, bugusers
>   printvars.aspx, printvars.c, printvars.exe
>
>To install
>0. Take one working Apache 2/ mod_aspdotnet install
>1. Copy printvars.* into c:\temp\aspnetbug\  ( or directory of your choice )
>2. If you don't trust me, compile printvars.c with the compiler of your choice
>3. Copy aspnetbug.conf and bugusers to c:\Program Files\Apache Group\Apache2\conf\  (or wherever)
>4. Add the following line to c:\Program Files\Apache Group\Apache2\conf\httpd.conf:
>   include conf/aspnetbug.conf
>
>To test
>1. Navigate  browser to http://localhost/aspnetbug/printvars.exe
>Observed:
> requires a login. Log in as username = test, password=  test
> Web page shows:
>
>SERVER_SOFTWARE=Apache/2.0.53 (Win32)
>REMOTE_USER=test
>AUTH_TYPE=Basic
>
>2. Navigate browser to http://localhost/aspnetbug/printvars.aspx (and login as before if required)
>Observed:
>Variable    ServerVariables[x]   GetServerVariables(x)
>AUTH_TYPE    (blank)    Basic
>AUTH_USER    (blank)    (blank)   
>REMOTE_USER    (blank)    test
>SERVER_SOFTWARE    Apache/2.0.53 (Win32)    Apache/2.0.53 (Win32)
>
>Expected:
>For the Request.ServerVariables to match what came back from GetServerVariables(), of course.
>
>Comments:
>OK, clearly ASP.NET is not using the server variables passed to it to determine the authenticated user.  Quite what it thinks it is using I don't know, but GetUserToken() seems like a very likely place.
>
>Perhaps this thread should be titled "mod_aspdotnet does not implement GetUserToken()"
>
>How to fix this is another problem. How does the value (IntPtr) returned by GetUserToken() turn into the ASP.NET User object (assuming it does!). Digging the MSDN documentation it appear that someone somewhere should be executing code like:
>
>IPrincipal aspnet_user_object = new GenericPrincipal(
>   new GenericIdentity( GetServerVariables( "REMOTE_USER"), GetServerVariables("AUTH_TYPE") ),
>   null );
>// that now becomes the ASP.NET User object.
>
>Is it as simple as casting that aspnet_user_object to an IntPtr and returning that?  I surely don't think so.
>
>I really have run out of time on this. I hope this sheds some light, I can't see how mod_aspdotnet can be used for anything other that toy apps without it though.  Every application I've ever written has wanted to know who the user is, even if just for logging.
>
>Couple more things while they come to mind
>* mod_ntlm would present its own problems in that instead of returning a GenericPrincipal it should presumably be returning a WindowsPrincipal instead. I suspect this might involve more than just "new WindowsPrincipal( r->user )"
>* Would also be nice to add a list of roles so that ASP.NET code can use User.IsInRole().   Don't know where that list should be obtained, though. I don't know the request_rec structure at all so there might be something useful in there, might not.
>
>Enough,
>Walter
>
>
>
>
>
>
>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
>For additional commands, e-mail: cli-users-help@httpd.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
For additional commands, e-mail: cli-users-help@httpd.apache.org


Re: [cli-users] mod_aspdotnet does not pass authentication info on to ASP.NET

Posted by Walter Nicholls <wa...@cornerstone.co.nz>.
OK, I've wasted way too much time on this but I've eliminated two red 
herrings, IIS and the GetServerVariables() method

Here's a repro:

Attached zip file contains:
    aspnetbug.conf, bugusers
    printvars.aspx, printvars.c, printvars.exe

To install
0. Take one working Apache 2/ mod_aspdotnet install
1. Copy printvars.* into c:\temp\aspnetbug\  ( or directory of your choice )
2. If you don't trust me, compile printvars.c with the compiler of your 
choice
3. Copy aspnetbug.conf and bugusers to c:\Program Files\Apache 
Group\Apache2\conf\  (or wherever)
4. Add the following line to c:\Program Files\Apache 
Group\Apache2\conf\httpd.conf:
    include conf/aspnetbug.conf

To test
1. Navigate  browser to http://localhost/aspnetbug/printvars.exe
Observed:
  requires a login. Log in as username = test, password=  test
  Web page shows:

SERVER_SOFTWARE=Apache/2.0.53 (Win32)
REMOTE_USER=test
AUTH_TYPE=Basic

2. Navigate browser to http://localhost/aspnetbug/printvars.aspx (and 
login as before if required)
Observed:
Variable    ServerVariables[x]   GetServerVariables(x)
AUTH_TYPE    (blank)    Basic
AUTH_USER    (blank)    (blank)   
REMOTE_USER    (blank)    test
SERVER_SOFTWARE    Apache/2.0.53 (Win32)    Apache/2.0.53 (Win32)

Expected:
For the Request.ServerVariables to match what came back from 
GetServerVariables(), of course.

Comments:
OK, clearly ASP.NET is not using the server variables passed to it to 
determine the authenticated user.  Quite what it thinks it is using I 
don't know, but GetUserToken() seems like a very likely place.

Perhaps this thread should be titled "mod_aspdotnet does not implement 
GetUserToken()"

How to fix this is another problem. How does the value (IntPtr) returned 
by GetUserToken() turn into the ASP.NET User object (assuming it does!). 
Digging the MSDN documentation it appear that someone somewhere should 
be executing code like:

 IPrincipal aspnet_user_object = new GenericPrincipal(
    new GenericIdentity( GetServerVariables( "REMOTE_USER"), 
GetServerVariables("AUTH_TYPE") ),
    null );
// that now becomes the ASP.NET User object.

Is it as simple as casting that aspnet_user_object to an IntPtr and 
returning that?  I surely don't think so.

I really have run out of time on this. I hope this sheds some light, I 
can't see how mod_aspdotnet can be used for anything other that toy apps 
without it though.  Every application I've ever written has wanted to 
know who the user is, even if just for logging.

Couple more things while they come to mind
 * mod_ntlm would present its own problems in that instead of returning 
a GenericPrincipal it should presumably be returning a WindowsPrincipal 
instead. I suspect this might involve more than just "new 
WindowsPrincipal( r->user )"
 * Would also be nice to add a list of roles so that ASP.NET code can 
use User.IsInRole().   Don't know where that list should be obtained, 
though. I don't know the request_rec structure at all so there might be 
something useful in there, might not.

Enough,
Walter










---------------------------------------------------------------------
To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
For additional commands, e-mail: cli-users-help@httpd.apache.org


Re: [cli-users] mod_aspdotnet does not pass AUTH_TYPE or REMOTE_USER value?

Posted by Walter Nicholls <wa...@cornerstone.co.nz>.
William A. Rowe, Jr. wrote:

>Your issue is with NTLM auth.  If you don't attempt to use system
>credentials, all should work better.  
>
It's not, and I'm not. NTLM is a red herring. In fact, IIS is probably a 
red herring but it does show the system working. Yes, I am using LAN 
credentials with IIS, but that's because I have no other choice unless I 
go to an awful lot of trouble. That's also one of the reasons why I want 
to get Apache going: I do know about mod_ntlm, but if I were to go down 
this route I might as well stay with IIS and save a whole lot of trouble. 


httpd.conf:
<Directory ...>
 .....
    AuthType basic
    AuthName "VP3 Prototype"
    AuthUserFile "conf/vp3users"
    AuthGroupFile "conf/vp3groups"
    Require group vp3
</Directory>

and vp3users:
  Walter:$apr1$Js3.....$wbYWPSNTdICVXr6lTi8d//
  .. etc ..
and vp3groups:
  vp3: Walter Beryl

This is definitely requiring login and it is definitely not using NTLM.  
If I log on as Walter or Beryl, I get in, if I login as Charlie I am 
denied access.

CGI Spec, http://hoohoo.ncsa.uiuc.edu/cgi/env.html:
* AUTH_TYPE
   If the server supports user authentication, and the script is 
protects, this is the protocol-specific authentication method used to 
validate the user.
* REMOTE_USER
   If the server supports user authentication, and the script is 
protected, this is the username they have authenticated as.
 
With the httpd.conf above, then these should be set to "Basic" and 
"Walter" respectively, When I go to http://localhost/../testvars.cmd, 
they are. When I go to http://localhost/.../Default.aspx, they are not. 
For examples in both cases see my first post.

I'm only guessing, but it's a pretty good guess, that the problem lies 
inside the mod_aspdotnet source code.

Looking closer at the httpd and the mod_aspdotnet source code, the 
REMOTE_USER and AUTH_TYPE environment variables seem to be set by the 
function ap_add_common_vars() defined in server/util_script.c. This 
function is called from both the CGI handler and the asp.net handler, so 
I really don't understand why these variables don't seem to be set by 
the time my C# code is called.






---------------------------------------------------------------------
To unsubscribe, e-mail: cli-users-unsubscribe@httpd.apache.org
For additional commands, e-mail: cli-users-help@httpd.apache.org