Difference between revisions of "Authentication"

From WeBWorK_wiki
Jump to navigation Jump to search
m
Line 9: Line 9:
 
* [[External_(Cosign)_Authentication|Authen::Cosign]] The Authen::Cosign module is designed to allow authentication with a system that manages authentication by way of web-server level configuration. That is, in this case you must be able to tell your apache server that given directories (that is, the course directories) are protected by your authentication system, and then the web server takes care of the redirect that is required for the user to log in. Then if the user ever gets to WeBWorK we know that s/he has authenticated and have only to check that the user is in the correct course roster. This is explained in the course of
 
* [[External_(Cosign)_Authentication|Authen::Cosign]] The Authen::Cosign module is designed to allow authentication with a system that manages authentication by way of web-server level configuration. That is, in this case you must be able to tell your apache server that given directories (that is, the course directories) are protected by your authentication system, and then the web server takes care of the redirect that is required for the user to log in. Then if the user ever gets to WeBWorK we know that s/he has authenticated and have only to check that the user is in the correct course roster. This is explained in the course of
 
* [[LDAP_Authentication|Authen::LDAP]] This is "similar" to Cosign authentication, but in this case we have to do more work to figure out if the user is valid. This is illustrated in the explanation below.
 
* [[LDAP_Authentication|Authen::LDAP]] This is "similar" to Cosign authentication, but in this case we have to do more work to figure out if the user is valid. This is illustrated in the explanation below.
* Authen::Moodle A module to allow authentication through Moodle.
+
* Authen::Moodle A module to allow authentication through Moodle. (DEPRECATED)
  +
** This module assumes that a copy of moodle (version 1.6 I believe) uses the same mysql installation as WeBWorK. Authentication is accomplished by redirecting the "user" table for WeBWorK to the "user" table of moodle. One must also configure WeBWorK to use the <code>sql_moodle</code> schema by setting the appropriate flags in <code>global.conf</code> and <code>database.conf</code>. This authentication method is very fragile and requires specific versions of moodle and WeBWorK. It is no longer supported. The current interoperability of moodle and WeBWorK described at [[Moodle_Integration]] does not use this module.
   
 
== WeBWorK's Authentication Process ==
 
== WeBWorK's Authentication Process ==

Revision as of 11:19, 5 August 2008

Authentication

By default, WeBWorK manages how users (students and instructors) authenticate to be allowed access to resources. There are a number of modules that allow WeBWorK to defer to another authentication source, e.g., so that it can use a central login service on a campus. The different implementations of such external authentication resources are indicated below. The remainder of this document describes generally how authentication is managed in WeBWorK, to inform how the existing modules work and provide some background information about how to set up a new one.

Existing Authen Modules

There are currently several WeBWorK authentication modules to allow it to use an external authentication system:

  • Authen::Cosign The Authen::Cosign module is designed to allow authentication with a system that manages authentication by way of web-server level configuration. That is, in this case you must be able to tell your apache server that given directories (that is, the course directories) are protected by your authentication system, and then the web server takes care of the redirect that is required for the user to log in. Then if the user ever gets to WeBWorK we know that s/he has authenticated and have only to check that the user is in the correct course roster. This is explained in the course of
  • Authen::LDAP This is "similar" to Cosign authentication, but in this case we have to do more work to figure out if the user is valid. This is illustrated in the explanation below.
  • Authen::Moodle A module to allow authentication through Moodle. (DEPRECATED)
    • This module assumes that a copy of moodle (version 1.6 I believe) uses the same mysql installation as WeBWorK. Authentication is accomplished by redirecting the "user" table for WeBWorK to the "user" table of moodle. One must also configure WeBWorK to use the sql_moodle schema by setting the appropriate flags in global.conf and database.conf. This authentication method is very fragile and requires specific versions of moodle and WeBWorK. It is no longer supported. The current interoperability of moodle and WeBWorK described at Moodle_Integration does not use this module.

WeBWorK's Authentication Process

WeBWorK controls authentication to the homework system in the Authen.pm module. To verify that a user is authorized to access the WeBWorK system, it the module checks, in order

$self->get_credentials;
$self->check_user;
$self->verify_normal_user;

or, if the user is a practice (guest) user, the last is replaced with

$self->verify_practice_user;

These methods, respectively, get the user's login name and authentication credentials, then check that the user is a valid WeBWorK user, and finally, checks that the authentication credentials match those for the user.

The verify_normal_user routine is also configured to easily allow separate site authentication: in pseudo-code, it checks authentication with

if ( $self->valid_webwork_session() ) {
    return 1;
} else {
    if ( $self->checkPassword( $user_id, $password ) ) {
        $self->create_session();
        return 1;
    } elsif ( $self->can( site_checkPassword ) &&
              $self->site_checkPassword( $user_id, $password ) ) {
        $self->create_session();
        return 1;
    } else {
        return 0;
    }
}

Accordingly, if we want to develop a new authentication module, we need to replace one or more of these methods in a subclass of the Authen module. This is considered below in the examples.


Examples

Cosign

Cosign (Collaborative single-sign on) is an open source project originally designed to provide the University of Michigan with a secure single sign-on web authentication system. It is part of the National Science Foundation Middleware Initiative (NMI) EDIT software release.

Cosign runs as an apache module (as does WeBWorK), so that authentication through Cosign is based on the location that is being accessed. This means that if we configure the apache server to recognize a WeBWorK course as being Cosign protected the web server will automatically redirect the user to the Cosign login if the user isn't authenticated with Cosign, and won't allow the user to access the resource if the user isn't authenticated. This makes using Cosign pretty easy: we tell our webserver to protect a WeBWorK course with Cosign, and then if the user actually gets to the course we know that they've already successfully authenticated against the central login server.

Thus, in our Authen::Cosign.pm module, we have only two small changes:

  • In $self->get_credentials we have to get the user's login information from Cosign, not from a WeBWorK form;
  • In $self->site_checkPassword we just return 1 (true), because we know that if the user checked correctly in check_user and we've entered the WeBWorK system, then the user has both successfully authenticated against the central server and is a valid WeBWorK user.

We don't have to change the checkUser method, but we do have to be sure that the classlist in the WeBWorK class is kept up-to-date.

get_credentials

The simplest get_credentials method for Cosign authentication gets the user's login name from the environment (Cosign assures that this is set), and then forces verify_normal_user to fall through to the site_checkPassword routine:

sub get_credentials {
    my ($self) = @_;
    my $r = $self->{r};
    my $ce = $r->ce;
    my $db = $r->db;
    #
    # Cosign makes sure that the environment variable REMOTE_USER
    #    is set for us.
    if ( defined( $ENV{REMOTE_USER} ) ) {
        $self->{user_id} = $ENV{REMOTE_USER};
        $self->{r}->param("user", $ENV{REMOTE_USER});
    } else {
        return 0;
    }
    # we set the external auth parameter so that Login.pm knows
    #    what error to return if there's a check_user failure.
    $self->{external_auth} = 1;
    #
    # set other parameters to force a password check that will
    #    call site_checkPassword
    $self->{session_key} = undef;
    $self->{password} = 'youWouldNeverPickThisPassword';
    $self->{credential_source} = params;
    #
    return 1;
}

site_checkPassword

Because of the availability of the site_checkPassword function in verify_normal_user, we just have to provide such a routine:

sub site_checkPassword {
    my ( $self, $userID, $clearTextPassword ) = @_;
    # if we got here, we know we've already successfully authenticated against
    #    Cosign!
    return 1;
}

The actual code in Authen::Cosign.pm is slightly more complicated, but not much; see the module in the CVS for comparison.


LDAP

LDAP is a protocol to allow networked access to directory information (e.g., usernames and passwords). Therefore, to use it to authenticate WeBWorK users, we have to replace the checkPassword or site_checkPassword routines to query the LDAP server to find if the user is valid.

The simplest LDAP authentication system would therefore not have to change either of the get_credentials or check_user methods, and could leave checkPassword as well as long as the LDAP password didn't match the password in WeBWorK. This implementation would have

sub site_checkPassword {
    my ( $self, $userID, $clearTextPassword ) = @_;
    if ( $self->ldap_authen_uid( $userID, $clearTextPassword ) ) {
        return 1;
    } else {
        return 0;
    }
}

and then the routine ldap_authen_uid would check against the LDAP server. Alternately, we might want to first authenticate against LDAP, and if that fails, authenticate against the standard WeBWorK passwords. This requires changing checkPassword, as suggested by the following example.

sub checkPassword {
    my ( $self, $userID, $clearTextPassword ) = @_;
    if ( $self->ldap_authen_uid( $userID, $clearTextPassword ) ) {
        return 1;
    } else {
        return $self->SUPER::checkPassword($userID, $clearTextPassword);
    }
}

Note that in this case we can omit the site_checkPassword method. If we didn't want to authenticate against the WeBWorK database, the call to $self->SUPER::checkPassword could be replaced with a return 0 to force failure in that case.

In either case, the ldap_authen_uid routine must check the user with the LDAP server. For the actual (somewhat more complicated) implementation of checkPassword, and the code for ldap_authen_uid, see the module in the CVS.


MercedCAS