Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Authentication Headers without .NET. Possible?

I was wondering if anyone knew of a way to use Windows Authentication without hosting on an ASP site. It's an intranet w/ access to LDAP, so I'm wondering if there's a way to force the client to provide me the data as if it was coming from an ASP site. I just need the login domain and username and I can run from there. Using Node.js on Ubuntu. Anyone have any experience with this?

like image 605
A Wizard Did It Avatar asked Mar 14 '11 20:03

A Wizard Did It


1 Answers

Update: There's now a module that implements Windows-integrated authentication.


In your 401 response, you need to provide a WWW-Authenticate header with a value of NTLM, which informs browsers that they need to send Windows credentials.

response.writeHead(401, {
    'WWW-Authenticate': 'NTLM',
});

You then have the fun of implementing NTLM authentication. Quoting from this document about the NTLM authentication protocol:


  1. The client requests a protected resource from the server:

    GET /index.html HTTP/1.1
    
  2. The server responds with a 401 status, indicating that the client must authenticate. NTLM is presented as a supported authentication mechanism via the WWW-Authenticate header. Typically, the server closes the connection at this time:

    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: NTLM
    Connection: close
    

    Note that Internet Explorer will only select NTLM if it is the first mechanism offered; this is at odds with RFC 2616, which states that the client must select the strongest supported authentication scheme.

  3. The client resubmits the request with an Authorization header containing a Type 1 message parameter. The Type 1 message is Base-64 encoded for transmission. From this point forward, the connection is kept open; closing the connection requires reauthentication of subsequent requests. This implies that the server and client must support persistent connections, via either the HTTP 1.0-style "Keep-Alive" header or HTTP 1.1 (in which persistent connections are employed by default). The relevant request headers appear as follows:

    GET /index.html HTTP/1.1
    Authorization: NTLM TlRMTVNTUAABAAAABzIAAAYABgArAAAACwALACAAAABXT1JLU1RBVElPTkRPTUFJTg==
    
  4. The server replies with a 401 status containing a Type 2 message in the WWW-Authenticate header (again, Base-64 encoded). This is shown below.

    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: NTLM TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=
    
  5. The client responds to the Type 2 message by resubmitting the request with an Authorization header containing a Base-64 encoded Type 3 message:

    GET /index.html HTTP/1.1
    Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGoAAAAYABgAggAAAAwADABAAAAACAAIAEwAAAAWABYAVAAAAAAAAACaAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAVwBPAFIASwBTAFQAQQBUAEkATwBOAMM3zVy9RPyXgqZnr21CfG3mfCDC0+d8ViWpjBwx6BhHRmspst9GgPOZWPuMITqcxg==
    
  6. Finally, the server validates the responses in the client's Type 3 message and allows access to the resource.

     HTTP/1.1 200 OK
    

It should be easy enough to get the user's username – it's sent as plain text in the Type 3 message. Actually validating that they've supplied the correct password is another matter entirely. Implementing all of this is left as an exercise for the reader.

like image 116
josh3736 Avatar answered Oct 13 '22 06:10

josh3736