Re: Custom Authentication ISAPI Filter on CE 3.0

From: John Spaith [MS] (jspaith_at_ONLINE.microsoft.com)
Date: 12/14/04


Date: Tue, 14 Dec 2004 12:09:38 -0800

Yes, this is a very odd problem and sorry you've been struggling with this.
Your good detective work makes my job easier though. The short answer is
that this behavior is by design - whether it's good design is an open
question.

By design, the web server will SF_NOTIFY_AUTHENTICATION once per HTTP
session. So if you have multiple HTTP requests coming over the same TCP
connection, only the first request will have the filter called and the rest
do not. I'm almost positive I was inspired by this design from the way that
IIS implemented this. Whenever CE Web Server begins reading a new HTTP
request (even on same HTTP session), it will NULL out the user name and
password information. That's why your subsequent calls in the ISAPI
extension to get the user name end up returning blank.

On IIS one way this could work would be that your filter would copy a user
name and password into the header and then IIS would use those credentials
to impersonate the client. I assume the impersonation token lasts the
length of the session, and not just the request. Since CE doesn't have the
ImpersonateUser goo, this isn't an option for us.

One way to do what you're trying to do would be to use TLS. TLS allows you
to associate data with a particular thread - see TlsGetValue/TlsAlloc and
friends. This will allow your ISAPI filter to asssociate the
username/password of the user and the ISAPI extension to retrieve it later
on. HTTPD only services a request on the same thread. BE VERY CAREFUL -
HTTPD has a thread pool and will reuse the same thread for multiple requests
in theory. I'm reasonably sure my architecture below is legit, but think it
through very carefully for any corner cases I may be missing. I've never
tried to implement this myself.

So I'd implement this as something like:
1) In the GetFilterVersion, call TlsAlloc() and store the index returned.
Make it available to the ISAPI extensions somehow too.
2) In filter SF_NOTIFY_AUTHENTICATION, allocate a structure that contains
user name and password and any other interesting info and fill this in with
the data from the request. Store this struct with TlsSetValue(). So

MyCreds *p = new MyCreds(szUserName,szPassword);
TlsSetValue(dwIndex,p)

3) In your ISAPI extension, use TlsGetValue() to see if the MyCreds struct
has been set. Take appropriate action. This is the same as using the
REMOTE_USER you were originally planning on.

4) Have your filter get the SF_NOTIFY_END_OF_NET_SESSION indication. Free
the MyCreds structure and TlsSetValue(dwIndex,0) so that if another HTTP
session is handled on this thread, you won't reuse credentials from the
previous session.

-- 
John Spaith
Software Design Engineer, Windows CE
Microsoft Corporation
Check out the new CE Networking Team Blog at http://blogs.msdn.com/cenet/.
This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use. © 2003 Microsoft Corporation. All rights 
reserved.
<tcaminus-ola@yahoo.com> wrote in message 
news:1102989678.477050.36980@c13g2000cwb.googlegroups.com...
> This is a rather bizarre problem (in my opinion) and will take a bit of
> explaining, so please bear with me...
>
>
> I have implemented an ISAPI filter that performs custom authentication
> by handling the SF_NOTIFY_AUTHENTICATION event. All works well as far
> as authentication goes. The problem comes in when trying to get the
> current authenticated user name in an ISAPI Extension (NOT the filter),
> using GetServerVariable to return AUTH_USER. All the pages on the site
> are written as ISAPI extensions, and in several cases I need to know
> the security level of the logged in user, as different options will be
> rendered based on their security level. The first time a page is
> accessed, it works fine. But, if the user presses Refresh on the
> browser, GetServerVariable returns an empty value for AUTH_USER. I
> should also point out that this problem only manifests itself when the
> web page includes at least one other resource, such as an image or .css
> file.
>
> I have monitored the communication with a network analyzer, and have
> put trace statements in my auth filter so I can see what events are
> being called. I can see what is happening, I just don't know why. On
> the initial page request, the authentication event is called for both
> the ISAPI dll, and the header image (just a normal .gif that is
> displayed at the top of the page). The sniffer shows this as two
> separate TCP sessions. So far, so good... But when I refresh the page,
> I lose the authenticated user (at least, when trying to access it via
> the AUTH_USER server variable). The authentication event is ONLY called
> for the image, and not the ISAPI dll. At this point, I cannot determine
> who the authenticated user is. Again looking at the network capture, I
> see a difference. This time, BOTH the ISAPI dll and image GET requests
> are within the same TCP session. By the way, the "Authorization:
> Basic..." information IS in the header of BOTH GET requests, but the
> GET of the image occurs first, and that is the only resource for which
> the authentication notification is triggered. It seems that if the
> filter doesn't get called for the ISAPI dll (the actual "page"), I'm
> not able to determine the user name, as the AUTH_USER server variable
> is empty in this case. (I have also tried REMOTE_USER, but with the
> same results).
>
> Please note that my web application is running on the Windows CE 3.0
> web server, which implements a subset of the HTTP/1.0 protocol, and has
> a limited API. I am NOT using the Basic Authentication feature in the
> web server, as the users logging in are not "Windows users". I'm trying
> to manage everything through the custom authentication filter. I hope
> someone can help as this problem has been driving me crazy for nearly
> two weeks.
>
> Thanks,
>
> Tony
> 


Relevant Pages

  • Custom Authentication ISAPI Filter on CE 3.0
    ... I have implemented an ISAPI filter that performs custom authentication ... and not the ISAPI dll. ...
    (microsoft.public.windowsce.app.development)
  • OWA, FBA, and the front-end back end authentication process.
    ... The filter lets the request pass through unmodified, ... Exchange front-end server processes the request. ... the request still has no valid authentication header. ...
    (microsoft.public.exchange.admin)
  • Re: OWA, FBA, and the front-end back end authentication process.
    ... The filter lets the request pass through unmodified, ... >Exchange front-end server processes the request. ... the request still has no valid authentication header. ...
    (microsoft.public.exchange.admin)
  • Re: ISAPI Authentication
    ... There are lots of ways to implement authentication filters on ISAPI. ... Your filter can then change them to whatever username ... client will be sent in the clear. ...
    (microsoft.public.inetserver.iis.security)
  • Re: How to create a simple http request
    ... You should write the filter using a CHttpFilter derived class. ... written a filter but I have written few ISAPI extensions in the past. ... To parse XML returned from Tomcat you might want to use SAX ...
    (microsoft.public.vc.mfc)