Optional NTLM authentication for a website on Apache with PHP

This article shows how to configure the Apache webserver and a PHP website to optionally use NTLM authentication (Integrated Windows Authentication) to authenticate the website’s users. That means, a user may log in via his or her Windows account but does not have to. If he cannot be logged on (automatically), he just gets shown the basic website without the content for only logged on users.

First of all, you need to configure your Apache webserver to use NTLM authentication against your Windows domain. I followed this step-by-step guide to make it work: Using the NTLM part of Samba for Apache on Linux.

Then you need to configure the webserver so that access to the file auth.php is restricted to authenticated Windows users:

  1. <Files "auth.php">
  2.   # require the user to login via his Windows account when accessing auth.php
  3.   NTLMAuth on
  4.   AuthType NTLM
  5.   AuthName "NTLM Authentication"
  6.   NTLMAuthHelper "/usr/bin/ntlm_auth –helper-protocol=squid-2.5-ntlmssp"
  7.   NTLMBasicAuthoritative on
  8.   Require valid-user
  9.   # if the user cannot be authenticated he gets redirected to the main page
  10.   ErrorDocument 401 /index.php
  11. </Files>

If the user gets authenticated, auth.php stores the Windows username in the user’s session like this:

  1. // NTLM sets REMOTE_USER to the current Windows username automatically
  2. $_SESSION[‚username‘] = $_SERVER[‚REMOTE_USER‘];
  3. header("Location: index.php");

Now, if the user opens the main page of the website (index.php) for the first time he needs to be redirected to auth.php to authenticate. If the authentication fails, he gets re-redirected to index.php (via ErrorDocument 401 index.php in the Apache config) and is not logged on but may browse the content of the site that is visible to everybody. But if he got authenticated correctly he is now able to see the complete content of the website.

  1. $username = "";
  2. $user_is_logged_in = false;
  3.  
  4. // when the user visits the site for the first time
  5. // he has not yet been authenticated and his session is empty
  6. if (!isset($_SESSION[‚username‘]))
  7. {
  8.     // initialize the username so the user does not get
  9.     // redirected over and over again
  10.     $_SESSION[‚username‘] = "";
  11.     header("Location: auth.php");
  12. }
  13. else
  14. {
  15.     $username = trim($_SESSION[‚username‘]);
  16.     // if the user got authenticated, auth.php stored the
  17.     // username in the session
  18.     if ($username != "")
  19.     {
  20.         $user_is_logged_in = true;
  21.     }
  22. }
  23.  
  24. if (!$user_is_logged_in)
  25. {
  26.     echo ’not logged in<br/>‘;
  27.     echo ‚<a href="auth.php">login</a><br/>‘;
  28. }
  29. else
  30. {
  31.     echo ‚logged in as: ‚ . $username . ‚<br/>‘;
  32.     echo ‚content only visible for logged in users<br/>‘;
  33. }
  34.  
  35. echo ‚content visible for all users<br/>‘;

Download example website

Über uns Stefan

Polyglot Clean Code Developer

4 Kommentare

  1. Vielen Dank, du hast mich auf den richtigen Weg gebracht mit diesem Script!

  2. Pingback:Optional NTLM authentication in Apache - Just just easy answers

  3. Pingback:Aus AD die Email und AnzeigeName auslesen (PHP)

  4. Hi,
    can you recognize inside php script, credentials are got from browser popup/prompt, or automatically from authenticated to station domain user without prompting for credentials?
    If yes, how to do it?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax