OIDC and .htaccess on CSAIL webservers

Restricting access with OIDC and .htaccess on CSAIL webservers

The below formulas can be included in an .htaccess files on any of the CSAIL standard Web servers (people, groups, projects, courses).

If you are looking to setup your own Apache web-server with CSAIL OIDC Authentication, see: Configuring your own Apache Server with OIDC Authentication

Requiring CSAIL login via OpenID Connect

On servers where OpenID Connect is enabled (currently people, groups, projects, courses) the following recipe will require users to have a valid CSAIL account. This is only supported for https links, not unencrypted http, for security reasons. The user will be redirected to the OpenID Connect authentication server if they are not already logged in, and then redirected back to your page after authorization is completed.

To redirect from http to https:

RewriteEngine on
RewriteBase /PATH/TO/HERE
# Use this line only if a script cares about the identity of the client:
SSLOptions +OptRenegotiate +StdEnvVars
# Otherwise, comment out the previous line and uncomment the following line:
# SSLOptions +OptRenegotiate
SSLVerifyClient require
SSLVerifyDepth 3
SSLRequire %{SSL_CLIENT_S_DN_O} == "MIT Computer Science & Artificial Intelligence Laboratory"
RewriteCond          %{HTTPS} !=on
RewriteRule          (.*) https://SERVER.csail.mit.edu/PATH/TO/HERE/$1

Require OpenID Connect

# This sets the default state of the directory to be "closed".
Require all denied

# Apache 2.4 Require directives are OR-ed together by default.
# We need AND behavior here.
<RequireAll>
    # Tell OIDC module to deny unauthenticated users
    Require valid-user
    # Disallow any access on unencrypted sessions (fallback)
    Require ssl
    # Require usue of CSAIL OIDC provider
    Require claim iss:https://oidc.csail.mit.edu/
</RequireAll>

# Enable OIDC processing on this directory (but doesn't require it).
AuthType openid-connect

Restricting to specific users or groups

To restrict to members of a specific group, add Require claim groups:groupname to the RequireAll block (note, not all AFS groups are available, only those with corresponding Unix/LDAP groups). To restrict to specific named individuals, add (inside RequireAll) the following:

    <RequireAny>
      Require claim email:user1@csail.mit.edu
      Require claim email:user2@csail.mit.edu
      …
    </RequireAny>

Digest authentication is more secure than using plaintext passwords (described in the next section). If your site is accessed by older tools or very old browsers that don’t support digest authentication, try using “basic” (plaintext password) authentication with SSL as described in the next section.

To limit access to a directory using digest authentication (also called “secure password authentication”), put the following in your .htaccess file:

AuthUserFile /path/to/your/directory/.htdigest
AuthGroupFile /dev/null
AuthName "Ben Bitdiddle's private files"
AuthType Digest
AuthDigestProvider file
AuthDigestDomain /URL/path/to/your/directory
Require all denied                                                                                                 
<RequireAll>                                                                                                       
    Require ssl                                                                                                    
    Require valid-user                                                                                             
</RequireAll> 

*Be sure to replace the AuthUserFile, AuthName, and AuthDigestDomain with the real information* <nop>AuthUserFile is the complete path to the .htdigest file (which you will create below). <nop>AuthName is a message that will be displayed at the password prompt. <nop>AuthDigestDomain is the URL path to the directory being protected. (For example, if you are protecting http://people.csail.mit.edu/bitdiddl/private/, the directive should read <nop>AuthDigestDomain /bitdiddl/private/.)

Next you need to run the htdigest command, available on public login servers, to create the password file you referenced in the above .htdigest file. For example, if you specified /afs/csail/.../public_html/testing/.htdigest as the password file, you would first ssh to a CSAIL login server then run:

$ htdigest -c ~/public_html/testing/.htdigest "Ben Bitdiddle's private files" bitdiddl
Adding password for bitdiddl in realm Ben Bitdiddle's private files.
New password: 
Re-type new password: 

Leave off the -c option for the second and subsequent users. The command means “Create the .htdigest file if it doesn’t exist or overwrite it if it does—that’s what the -c does—and create a user called bitdiddl using digest authentication.” Note that the passwords are specific to the “realm” you specify, which must be identical to the name specified in the <nop>AuthName directive in the .htdigest file.

(If you name your password file something other than .ht*, then you should store it outside of your web file tree. The server contains special access controls to prevent people from downloading these files, which will not apply if you call the password file something else.)

Note that the server will be accessing the .htaccess and .htdigest files, which means it needs to have permission to access them. The directory where you put .htdigest, being a subdirectory of your web directory, will likely inherit the permissions of the web directory, so the web server should already be able to read it. However, if you put .htdigest in another directory, it may not be readable by the web server unless you use the fs setacl command (e.g., fs sa DIR www read where DIR is the directory containing .htdigest).

Now you might want to make sure that the file got created and that everything looks good:

$ ls -la ~/public_html/testing/
total 12
drwxr-xr-x 2 wollman wollman 4096 May 28 13:42 ./
drwxr-xr-x 3 wollman wollman 4096 May 28 13:41 ../
-rw-r--r-- 1 wollman wollman   72 May 28 13:42 .htdigest
$ cat ~/public_html/testing/.htdigest
bitdiddl:Ben Bitdiddle's private files:e45c96567bc278d15a942e56dead09d9

Finally test this all by trying to browse to the web page you’re trying to protect. You should get a dialog prompting you for a username and password.

Restricting access using “basic” authentication

To limit access to a directory using plaintext password (called “basic”) authentication, put the following in your .htaccess file:

# Comment next two lines out to enable plaintext passwords over unencrypted
# connections.  Check with TIG if you are not sure whether you should.
SSLRequireSSL
SSLVerifyClient none
AuthUserFile /path/to/your/directory/.htpasswd
AuthGroupFile /dev/null
AuthName "Ben Bitdiddle's private files"
AuthType Basic
Require all denied                                                                                                 
<RequireAll>                                                                                                       
    Require ssl                                                                                                    
    Require valid-user                                                                                             
</RequireAll> 

*Be sure to replace the AuthUserFile and AuthName with the real information* <nop>AuthUserFile is the complete path to the .htpasswd file (which you will create below), and <nop>AuthName is a message that will be displayed at the password prompt.

Next you need to use the htpasswd command, available on public login servers, to create the password file you referenced in the above .htaccess file. For example, if you specified ~/testing/.htpasswd as the password file, you would then ssh to a CSAIL login server and run:

$ htpasswd -c .htpasswd testuser
New password: 
Re-type new password: 
Adding password for user testuser

This says, “Run the htpasswd command, and create the .htpasswd file if it doesn’t exist or overwrite it if it does (that’s what the -c does; be careful not to overwrite an existing file), and create a user called testuser.”

(If you name your password file something other than .htpasswd, then you should store it outside of your web file tree. The server contains special access controls to prevent people from downloading these files, which will not apply if you call the password file something else.)

Note that the server will be accessing the .htaccess and .htpasswd files, which means it needs to have permission to access them. The directory where you put .htaccess, being a subdirectory of your web directory, will likely inherit the permissions of the web directory, so the web server should already be able to read it. However, if you put .htpasswd in another directory, it may be readable by the web server unless you use the fs setacl command (e.g., fs sa DIR www read where DIR is the directory containing .htpasswd).

Now you might want to make sure that the file got created and that everything looks good:

mpearrow@asterix:~/testing$ ls -la
total 7
drwxrwxr-x   2 mpearrow mpearrow 2048 Feb  1 20:30 .
drwxrwxrwx  18 mpearrow      502 4096 Feb  1 20:29 ..
-rw-rw-r--   1 mpearrow mpearrow   23 Feb  1 20:30 .htpasswd
mpearrow@asterix:~/testing$ more .htpasswd 
testuser:Jo/nnqFPwqQqU
mpearrow@asterix:~/testing$ 

Finally test this all by trying to browse to the web page you’re trying to protect. You should get a dialog prompting you for a username and password.

Troubleshooting basic authentication

If this doesn’t work, you’ve probably put your .htpasswd file in a directory the Web server is not allowed to read. (Your home directory, for example, is a common place that people have put .htpasswd files in the past which is not readable by the Web server.)

Restricting Access by IP Address

If you want to limit access to a directory and its children based on IP address (e.g., just people on the CSAIL network, or MITnet, etc.) you also use a .htaccess file. For example, the following directive limits the directory and children to only MITnet and the CSAIL network:

Require all denied                                                                                                 
<RequireAny>                                                                                                       
    # CSAIL Networks                                                                                               
    Require ip 18.26.0.0/16                                                                                        
    Require ip 128.30.0.0/16                                                                                       
    Require ip 128.52.0.0/16                                                                                       
    Require ip 192.12.11.0/24                                                                                      
    # CSAIL "Guest" networks including unauthenticated wireless                                                     
    Require ip 128.31.0.0/16                                                                                       
    # MIT NET                                                                                                      
    Require ip 18.0.0.0/9                                                                                          
    Require ip 18.128.0.0/12                                                                                       
</RequireAny>    

Finding out more about .htaccess magic

See the Apache .htaccess page

If it still doesn’t work, send email to help@csail.mit.edu and we’ll help you sort it out.