http_openid.pl -- OpenID consumer and server library
This library implements the OpenID protocol (http://openid.net/). OpenID is a protocol to share identities on the network. The protocol itself uses simple basic HTTP, adding reliability using digitally signed messages.
Steps, as seen from the consumer (or relying partner).
- Show login form, asking for
openid_identifier
- Get HTML page from
openid_identifier
and lookup<link rel="openid.server" href="server">
- Associate to server
- Redirect browser (302) to server using mode
checkid_setup
, asking to validate the given OpenID. - OpenID server redirects back, providing digitally signed conformation of the claimed identity.
- Validate signature and redirect to the target location.
A consumer (an application that allows OpenID login) typically uses
this library through openid_user/3. In addition, it must implement the
hook http_openid:openid_hook(trusted(OpenId, Server))
to define accepted
OpenID servers. Typically, this hook is used to provide a white-list of
aceptable servers. Note that accepting any OpenID server is possible,
but anyone on the internet can setup a dummy OpenID server that simply
grants and signs every request. Here is an example:
:- multifile http_openid:openid_hook/1. http_openid:openid_hook(trusted(_, OpenIdServer)) :- ( trusted_server(OpenIdServer) -> true ; throw(http_reply(moved_temporary('/openid/trustedservers'))) ). trusted_server('http://www.myopenid.com/server').
By default, information who is logged on is maintained with the session
using http_session_assert/1 with the term openid(Identity)
. The hooks
login/logout/logged_in can be used to provide alternative administration
of logged-in users (e.g., based on client-IP, using cookies, etc.).
To create a server, you must do four things: bind the handlers
openid_server/2 and openid_grant/1 to HTTP locations, provide a
user-page for registered users and define the grant(Request, Options)
hook to verify your users. An example server is provided in in
<plbase>/doc/packages/examples/demo_openid.pl
- openid_hook(+Action)[multifile]
- Call hook on the OpenID management library. Defined hooks are:
- login(+OpenID)
- Consider OpenID logged in.
- logout(+OpenID)
- Logout OpenID
- logged_in(?OpenID)
- True if OpenID is logged in
- grant(+Request, +Options)
- Server: Reply positive on OpenID
- trusted(+OpenID, +Server)
- True if Server is a trusted OpenID server
- ax(Values)
- Called if the server provided AX attributes
- x_parameter(+Server, -Name, -Value)
- Called to find additional HTTP parameters to send with the OpenID verify request.
- openid_login(+OpenID) is det
- Associate the current HTTP session with OpenID. If another OpenID is already associated, this association is first removed.
- openid_logout(+OpenID) is det
- Remove the association of the current session with any OpenID
- openid_logged_in(-OpenID) is semidet
- True if session is associated with OpenID.
- openid_user(+Request:http_request, -OpenID:url, +Options) is det
- True if OpenID is a validated OpenID associated with the current
session. The scenario for which this predicate is designed is to
allow an HTTP handler that requires a valid login to
use the transparent code below.
handler(Request) :- openid_user(Request, OpenID, []), ...
If the user is not yet logged on a sequence of redirects will follow:
- Show a page for login (default: page /openid/login), predicate reply_openid_login/1)
- By default, the OpenID login page is a form that is
submitted to the
verify
, which calls openid_verify/2. - openid_verify/2 does the following:
- Find the OpenID claimed identity and server
- Associate to the OpenID server
- redirects to the OpenID server for validation
- The OpenID server will redirect here with the authetication information. This is handled by openid_authenticate/4.
Options:
- login_url(Login)
- (Local) URL of page to enter OpenID information. Default is the handler for openid_login_page/1
- openid_login_form(+ReturnTo, +Options)// is det
- Create the OpenID form. This exported as a seperate DCG,
allowing applications to redefine /openid/login and reuse this
part of the page. Options processed:
- action(Action)
- URL of action to call. Default is the handler calling openid_verify/1.
- buttons(+Buttons)
- Buttons is a list of
img
structures where thehref
points to an OpenID 2.0 endpoint. These buttons are displayed below the OpenID URL field. Clicking the button sets the URL field and submits the form. Requires Javascript support.If the
href
is relative, clicking it opens the given location after adding 'openid.return_to' and `stay'. - show_stay(+Boolean)
- If
true
, show a checkbox that allows the user to stay logged on.
- openid_verify(+Options, +Request)
- Handle the initial login form presented to the user by the
relying party (consumer). This predicate discovers the OpenID
server, associates itself with this server and redirects the
user's browser to the OpenID server, providing the extra
openid.X name-value pairs. Options is, against the conventions,
placed in front of the Request to allow for smooth cooperation
with http_dispatch.pl. Options processes:
- return_to(+URL)
- Specifies where the OpenID provider should return to. Normally, that is the current location.
- trust_root(+URL)
- Specifies the
openid.trust_root
attribute. Defaults to the root of the current server (i.e.,http://host[.port]/
). - realm(+URL)
- Specifies the
openid.realm
attribute. Default is thetrust_root
. - ax(+Spec)
- Request the exchange of additional attributes from the identity provider. See http_ax_attributes/2 for details.
The OpenId server will redirect to the
openid.return_to
URL. - openid_server(?OpenIDLogin, ?OpenID, ?Server) is nondet
- True if OpenIDLogin is the typed id for OpenID verified by Server.
- openid_current_url(+Request, -URL) is det
- Find the public URL for Request that we can make available to our identity provider. This must be an absolute URL where we can be contacted. Before trying a configured version through http_public_url/2, we try to see wether the login message contains a referer parameter or wether the browser provided one.
- openid_current_host(Request, Host, Port)
- Find current location of the server.
- openid_authenticate(+Request, -Server:url, -OpenID:url, -ReturnTo:url) is semidet
- Succeeds if Request comes from the OpenID server and confirms
that User is a verified OpenID user. ReturnTo provides the URL
to return to.
After openid_verify/2 has redirected the browser to the OpenID server, and the OpenID server did its magic, it redirects the browser back to this address. The work is fairly trivial. If
mode
iscancel
, the OpenId server denied. Ifid_res
, the OpenId server replied positive, but we must verify what the server told us by checking the HMAC-SHA signature.This call fails silently if their is no
openid.mode
field in the request. - openid_server(+Options, +Request)
- Realise the OpenID server. The protocol demands a POST request here.
- openid_grant(+Request)
- Handle the reply from checkid_setup_server/3. If the reply is
yes
, check the authority (typically the password) and if all looks good redirect the browser to ReturnTo, adding the OpenID properties needed by the Relying Party to verify the login. - openid_associate(?URL, ?Handle, ?Assoc) is det
- Calls openid_associate/4 as
openid_associate(URL, Handle, Assoc, []).
- openid_associate(+URL, -Handle, -Assoc, +Options) is det
- openid_associate(?URL, +Handle, -Assoc, +Options) is semidet
- Associate with an open-id server. We first check for a still
valid old association. If there is none or it is expired, we
esstablish one and remember it. Options:
- ns(URL)
- One of
http://specs.openid.net/auth/2.0
(default) orhttp://openid.net/signon/1.1
.