NAME
Apache2::Controller::Auth::OpenID - OpenID for Apache2::Controller
VERSION
Version 1.000.000 - FIRST RELEASE
UNIMPLEMENTED
UNIMPLEMENTED! Peril! Pitfalls! Pernicious knids!
SYNOPSIS
PerlLoadModule Apache2::Controller::Directives
<Location /myapp>
SetHandler modperl
# uri to your login controller:
A2C_Auth_OpenID_Login login
# uri to your logout controller:
A2C_Auth_OpenID_Logout logout
# uri to your registration controller:
A2C_Auth_OpenID_Register register
# you might want to put this outside the protected area,
# i.e. /other/register - you can use leading '/' for absolute uri
# idle timeout in seconds, +2m, +3h, +4D, +6M, +7Y, or 'no timeout'
# default is 1 hour. a month is actually 30 days, a year 365.
A2C_Auth_OpenID_Timeout +1h
# name of the openid table in database:
A2C_Auth_OpenID_Table openid
# key of the username field in table:
A2C_Auth_OpenID_User_Field uname
# key of the openid url field in table:
A2C_Auth_OpenID_URL_Field openid_url
# if you use multiple DBI handles, name the one in pnotes
# that you should use for reading the openid table:
A2C_Auth_OpenID_DBI_Name dbh
# by default trust_root is the result of $r->construct_url(''),
# i.e. the top of the site (see Apache::URI)
A2C_Auth_OpenID_Trust_Root http://myapp.tld/somewhere
# set a random string used as salt with time() to sha secret
A2C_Auth_OpenID_Consumer_Secret
# but that random salt will be reset if you restart server,
# which may cause current logins to die, so you can specify
# your own constant salt of arbitrary length
A2C_Auth_OpenID_Consumer_Secret abcdefg1234567
# PerlHeaderParserHandlers must be invoked in order
# to set up the session and dbi handle before checking auth
# In this example,
# MyApp::DBI::Connector is an Apache2::Controller::DBI::Connector
# and MyApp::Session is an Apache2::Controller::Session::Cookie...
# see those modules for more info.
PerlInitHandler MyApp::Dispatch
PerlHeaderParserHandler MyApp::DBI::Connector
PerlHeaderParserHandler MyApp::Session
PerlHeaderParserHandler Apache2::Controller::Auth::OpenID
</Location>
DESCRIPTION
Implements an authentication mechanism for Apache2::Controller that uses OpenID.
This is NOT an AuthenPerlHandler. This is an implementation of a simple cookie-based session mechanism that shows the browser a login page, where your controller should present and process an HTML form for logging in.
If you want an authentication handler that uses browser-based auth (the pop-up dialog implemented by HTTP auth protocol) use Apache::Authen::OpenID, which is not a part of Apache2::Controller but should work for you anyway.
Natively this depends on Apache2::Controller::Session::Cookie and Apache2::Controller::DBI::Connector being configured correctly, but you could always subclass this and overload the methods below to get information from other sources.
If no claimed ID is detected, the user is shown the login page. If an error occured, you'll find the Net::OpenID::Consumer error details in the session under {a2c}{openid}{errtext}
and {a2c}{openid}{errcode}
.
REDIRECTION OR REDISPATCH?
Whether redirecting or redispatching, stuff has to be saved in the session, so $r->notes->{a2c_session_force_save
will be set.
INTERNAL LOGIN, LOGOUT AND REGISTER PAGES
RELATIVE URIS - REDISPATCH
If the uris for these pages are relative, not absolute, i.e. they are handled by the same controller that we're going to anyway, then it tries setting the uri and re-dispatching by grabbing the dispatch class name out of $r->notes->{a2c_dispatch_class}
and instantiating a new dispatch handler object.
(Dispatch can't keep the handler subref around in pnotes due to circular references, or reliably assume that we know at what location in the PerlInitHandler
stack the dispatch handler coderef was stored by Apache, so we just create a new one - this is assured to be faster than creating an entire new request, which would do that anyway.)
So in this case, the content for the login, logout, or register pages will appear even though the browser uri still displays the requested protected URI.
ABSOLUTE URIS - REDIRECT
If the uris for the internal pages are absolute, i.e. they might be handled by a different controller than the one that was dispatched, a redirect using Location HTTP header is used.
EXTERNAL OPENID PAGES
Any time the browser needs to go to an external page (the openid server), a redirect using a Location: HTTP header is used.
PRESERVATION OF INITIAL REQUEST
REQUESTED URI
When it goes to your login, or register page, it stashes the user's uri into the session as {a2c}{openid}{previous_uri}
and should preserve this for the return url. It uses $r->construct_url()
as the trusted root.
When the user passes the authentication process ($csr->verified_identity
), it sets $r->notes->{a2c_openid_logged_in}
for this request to let your handler know if you want to display a message like "You have successfully logged in" or something.
POST VARS
not yet...
If redirected, it also stashes the POST body into the session as {a2c}{openid}{redirect_post}
but if you use this, you probably want to put some kind of form id and a unique value for every post so you're sure you're doing the right thing. I don't know if this will work, but it might be useful.
DIRECTIVES
"Apache2::Controller::Auth::OpenID" in Apache2::Controller::Directives
CACHING
If you want to provide a cache for Net::OpenID::Consumer to pass onto URI::Fetch, subclass this module and implement a method cache()
that returns the appropriate cache object.
CAVEATS
I have heard there are trickier things one can do to ensure the security of a session based cookie. This module just implements a simple association of a user with a session key by storing a flag and a last-accessed time value in the session hash, nothing fancier.
This calls $r->connection->get_remote_host
and saves it in the {a2c}{openid}
section of the session hash. So if you don't want it to do DNS lookups, set directive HostNameLookups off
.
METHODS
"These aren't the methods you're looking for."
"These aren't the methods we're looking for."
"He can go about his business."
"You can go about your business."
"Move along."
"Move along. Move along."
You don't access these methods. This is internal documentation.
default_directives
Calculate and return the hash of directive defaults. (Some of these are based on the current <Location> of the handler.)
openid_url_normalize
Correct trailing double /'s etc. in the openid url.
process
Make sure the config directives are assigned or use defaults.
If uri = login uri, process accordingly.
If uri = logout uri, delete session hash login flags and return OK.
qualify_uri
If the uri is relative, qualifies it by prepending current location. Otherwise just returns the uri.
redirect_to
return $self->redirect_to($uri);
If one of the three internal URIs, use redispatch()
.
Otherwise, use location_redirect
.
location_redirect
return $self->location_redirect($uri);
Set the Location header and return REDIRECT.
Forces the session to be saved in the cleanup handler.
redispatch
return $self->redispatch($uri);
For the internal pages (login, logout, register), if they are relative, re-dispatch them and return OK, else if absolute, set location and return redirect.
If where == register or login, and the current uri is not register or login, stash the current uri in session->{a2c}{openid}{previous_uri}
.
is_logged_in
Check the fields in the session hash to make sure they're logged in. Apply the directive timeout to make sure. Don't change anything though. Just return if not logged in, or return 1 if logged in.
logout
Log the user out by clearing the relevant fields in the session hash.
SEE ALSO
Apache2::Controller::Directives
Apache2::Controller::NonResponseRequest
AUTHOR
Mark Hedges, <hedges at scriptdolphin.org>
COPYRIGHT & LICENSE
Copyright 2008 Mark Hedges, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.