summaryrefslogtreecommitdiffstats
path: root/Net
diff options
context:
space:
mode:
authortailor <cygnus@janrain.com>2006-01-13 23:44:45 +0000
committertailor <cygnus@janrain.com>2006-01-13 23:44:45 +0000
commit3a09110c51b51ca2728993508d124162e2f966db (patch)
tree430af15623253397337b0be2896e35e0ec649b64 /Net
parentdb97dc546fe67ee18b404a9f26762a68ca7c4797 (diff)
downloadphp-openid-3a09110c51b51ca2728993508d124162e2f966db.zip
php-openid-3a09110c51b51ca2728993508d124162e2f966db.tar.gz
php-openid-3a09110c51b51ca2728993508d124162e2f966db.tar.bz2
[project @ Updated Consumer docs]
Diffstat (limited to 'Net')
-rw-r--r--Net/OpenID/Consumer/Consumer.php310
1 files changed, 281 insertions, 29 deletions
diff --git a/Net/OpenID/Consumer/Consumer.php b/Net/OpenID/Consumer/Consumer.php
index 5e29881..64d581a 100644
--- a/Net/OpenID/Consumer/Consumer.php
+++ b/Net/OpenID/Consumer/Consumer.php
@@ -9,33 +9,27 @@
* documentation for the constructor of the OpenIDConsumer class.
*
* OVERVIEW
- * ========
*
* The OpenID identity verification process most commonly uses the
* following steps, as visible to the user of this library:
*
- * 1. The user enters their OpenID into a field on the consumer's
- * site, and hits a login button.
- *
- * 2. The consumer site checks that the entered URL describes an
- * OpenID page by fetching it and looking for appropriate link tags
- * in the head section.
- *
- * 3. The consumer site sends the browser a redirect to the identity
- * server. This is the authentication request as described in the
- * OpenID specification.
- *
- * 4. The identity server's site sends the browser a redirect back
- * to the consumer site. This redirect contains the server's
- * response to the authentication request.
+ * 1. The user enters their OpenID into a field on the consumer's
+ * site, and hits a login button.
+ * 2. The consumer site checks that the entered URL describes an
+ * OpenID page by fetching it and looking for appropriate link tags
+ * in the head section.
+ * 3. The consumer site sends the browser a redirect to the identity
+ * server. This is the authentication request as described in the
+ * OpenID specification.
+ * 4. The identity server's site sends the browser a redirect back to
+ * the consumer site. This redirect contains the server's response
+ * to the authentication request.
*
* The most important part of the flow to note is the consumer's site
* must handle two separate HTTP requests in order to perform the full
* identity check.
*
- *
* LIBRARY DESIGN
- * ==============
*
* This consumer library is designed with that flow in mind. The goal
* is to make it as easy as possible to perform the above steps
@@ -56,12 +50,10 @@
* This module contains a class, Net_OpenID_Consumer, with methods
* corresponding to the actions necessary in each of steps 2, 3, and 4
* described in the overview. Use of this library should be as easy
- * as creating an Net_OpenID_Consumer instance and calling the methods
+ * as creating a Net_OpenID_Consumer instance and calling the methods
* appropriate for the action the site wants to take.
*
- *
* STORES AND DUMB MODE
- * ====================
*
* OpenID is a protocol that works best when the consumer site is able
* to store some state. This is the normal mode of operation for the
@@ -92,9 +84,7 @@
* should only be used if the consumer site has no way to retain data
* between requests at all.
*
- *
* IMMEDIATE MODE
- * ==============
*
* In the flow described above, the user may need to confirm to the
* identity server that it's ok to authorize his or her identity. The
@@ -113,9 +103,7 @@
* information and let the server finish handling the original
* request.
*
- *
* USING THIS LIBRARY
- * ==================
*
* Integrating this library into an application is usually a
* relatively straightforward process. The process should basically
@@ -192,6 +180,9 @@
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*/
+/**
+ * Require utility classes and functions for the consumer.
+ */
require_once("Net/OpenID/CryptUtil.php");
require_once("Net/OpenID/KVForm.php");
require_once("Net/OpenID/OIDUtil.php");
@@ -200,27 +191,95 @@ require_once("Net/OpenID/DiffieHellman.php");
require_once("Net/OpenID/Consumer/Parse.php");
require_once("Net/OpenID/Consumer/Fetchers.php");
+/**
+ * This is the status code returned when either the of the beginAuth
+ * or completeAuth methods return successfully.
+ */
$Net_OpenID_SUCCESS = 'success';
+
+/**
+ * This is the status code completeAuth returns when the value it
+ * received indicated an invalid login.
+ */
$Net_OpenID_FAILURE = 'failure';
+
+/**
+ * This is the status code completeAuth returns when the
+ * Net_OpenID_Consumer instance is in immediate mode, and the identity
+ * server sends back a URL to send the user to to complete his or her
+ * login.
+ */
$Net_OpenID_SETUP_NEEDED = 'setup needed';
+
+/**
+ * This is the status code beginAuth returns when it is unable to
+ * fetch the OpenID URL the user entered.
+ */
$Net_OpenID_HTTP_FAILURE = 'http failure';
+
+/**
+ * This is the status code beginAuth returns when the page fetched
+ * from the entered OpenID URL doesn't contain the necessary link tags
+ * to function as an identity page.
+*/
$Net_OpenID_PARSE_ERROR = 'parse error';
-// The following is a real hack and we'll have to figure out what is
-// going on. PHP bug?
+/**
+ * This is the characters that the nonces are made from.
+ */
$_Net_OpenID_NONCE_CHRS = $GLOBALS['_Net_OpenID_letters'] .
$GLOBALS['_Net_OpenID_digits'];
+/**
+ * This is the number of seconds the tokens generated by this library
+ * will be valid for. If you want to change the lifetime of a token,
+ * set this value to the desired lifespan, in seconds.
+ */
$_Net_OpenID_TOKEN_LIFETIME = 60 * 5; // five minutes
+
+/**
+ * This is the number of characters in the generated nonce for each
+ * transaction.
+ */
$_Net_OpenID_NONCE_LEN = 8;
+/**
+ * This class is the interface to the OpenID consumer logic.
+ * Instances of it maintain no per-request state, so they can be
+ * reused (or even used by multiple threads concurrently) as needed.
+ *
+ * @package OpenID
+ */
class Net_OpenID_Consumer {
/**
- * NOTE: Be sure to pass $fetcher by reference if you pass one at
- * all:
+ * This method initializes a new Net_OpenID_Consumer instance to
+ * access the library.
+ *
+ * @param Net_OpenID_OpenIDStore $store This must be an object
+ * that implements the interface in Net_OpenID_Store. Several
+ * concrete implementations are provided, to cover most common use
+ * cases. For stores backed by MySQL, PostgreSQL, or SQLite, see
+ * the Net_OpenID_SQLStore class and its sublcasses. For a
+ * filesystem-backed store, see the Net_OpenID_FileStore module.
+ * As a last resort, if it isn't possible for the server to store
+ * state at all, an instance of Net_OpenID_DumbStore can be used.
+ * This should be an absolute last resort, though, as it makes the
+ * consumer vulnerable to replay attacks over the lifespan of the
+ * tokens the library creates.
*
- * $consumer = new Net_OpenID_Consumer($store, &$fetcher, ...);
+ * @param Net_OpenID_HTTPFetcher $fetcher This is an optional
+ * reference to an instance of Net_OpenID_HTTPFetcher. If
+ * present, the provided fetcher is used by the library to fetch
+ * users' identity pages and make direct requests to the identity
+ * server. If it is not present, a default fetcher is used. The
+ * default fetcher uses curl if the Curl bindings are available,
+ * and uses a raw socket POST if not.
+ *
+ * @param bool $immediate This is an optional boolean value. It
+ * controls whether the library uses immediate mode, as explained
+ * in the module description. The default value is False, which
+ * disables immediate mode.
*/
function Net_OpenID_Consumer(&$store, $fetcher = null, $immediate = false)
{
@@ -247,6 +306,63 @@ class Net_OpenID_Consumer {
$this->immediate = $immediate;
}
+ /**
+ * This method is called to start the OpenID login process.
+ *
+ * First, the user's claimed identity page is fetched, to
+ * determine their identity server. If the page cannot be fetched
+ * or if the page does not have the necessary link tags in it,
+ * this method returns one of $Net_OpenID_HTTP_FAILURE or
+ * $Net_OpenID_PARSE_ERROR, depending on where the process failed.
+ *
+ * Second, unless the store provided is a dumb store, it checks to
+ * see if it has an association with that identity server, and
+ * creates and stores one if not.
+ *
+ * Third, it generates a signed token for this authentication
+ * transaction, which contains a timestamp, a nonce, and the
+ * information needed in Step 4 (above) in the module overview.
+ * The token is used by the library to make handling the various
+ * pieces of information needed in Step 4 (above) easy and secure.
+ *
+ * The token generated must be preserved until Step 4 (above),
+ * which is after the redirect to the OpenID server takes place.
+ * This means that the token must be preserved across http
+ * requests. There are three basic approaches that might be used
+ * for storing the token. First, the token could be put in the
+ * return_to URL passed into the constructRedirect method.
+ * Second, the token could be stored in a cookie. Third, in an
+ * environment that supports user sessions, the session is a good
+ * spot to store the token.
+ *
+ * @param string $user_url This is the url the user entered as
+ * their OpenID. This call takes care of normalizing it and
+ * resolving any redirects the server might issue.
+ *
+ * @return array $array This method returns an array containing a
+ * status code and additional information about the code.
+ *
+ * If there was a problem fetching the identity page the user
+ * gave, the status code is set to $Net_OpenID_HTTP_FAILURE, and
+ * the additional information value is either set to null if the
+ * HTTP transaction failed or the HTTP return code, which will be
+ * in the 400-500 range. This additional information value may
+ * change in a future release.
+ *
+ * If the identity page fetched successfully, but didn't include
+ * the correct link tags, the status code is set to
+ * $Net_OpenID_PARSE_ERROR, and the additional information value
+ * is currently set to null. The additional information value may
+ * change in a future release.
+ *
+ * Otherwise, the status code is set to $Net_OpenID_SUCCESS, and
+ * the additional information is an instance of
+ * Net_OpenID_AuthRequest. The $token attribute contains the
+ * token to be preserved for the next HTTP request. The
+ * $server_url might also be of interest, if you wish to blacklist
+ * or whitelist OpenID servers. The other contents of the object
+ * are information needed in the constructRedirect call.
+ */
function beginAuth($user_url)
{
global $Net_OpenID_SUCCESS;
@@ -260,6 +376,37 @@ class Net_OpenID_Consumer {
return $this->_gotIdentityInfo($consumer_id, $server_id, $server_url);
}
+ /**
+ * This method is called to construct the redirect URL sent to the
+ * browser to ask the server to verify its identity. This is
+ * called in Step 3 (above) of the flow described in the overview.
+ * The generated redirect should be sent to the browser which
+ * initiated the authorization request.
+ *
+ * @param Net_OpenID_AuthRequest $auth_request This must be a
+ * Net_OpenID_AuthRequest instance which was returned from a
+ * previous call to beginAuth. It contains information found
+ * during the beginAuth call which is needed to build the redirect
+ * URL.
+ *
+ * @param string $return_to This is the URL that will be included
+ * in the generated redirect as the URL the OpenID server will
+ * send its response to. The URL passed in must handle OpenID
+ * authentication responses.
+ *
+ * @param string $trust_root This is a URL that will be sent to
+ * the server to identify this site. The OpenID spec at
+ * http://www.openid.net/specs.bml#mode-checkid_immediate has more
+ * information on what the trust_root value is for and what its
+ * form can be. While the trust root is officially optional in
+ * the OpenID specification, this implementation requires that it
+ * be set. Nothing is actually gained by leaving out the trust
+ * root, as you can get identical behavior by specifying the
+ * return_to URL as the trust root.
+ *
+ * @return string $url This method returns a string containing the
+ * URL to redirect to when such a URL is successfully constructed.
+ */
function constructRedirect($auth_request, $return_to, $trust_root)
{
$assoc = $this->_getAssociation($auth_request->server_url,
@@ -277,6 +424,13 @@ class Net_OpenID_Consumer {
$return_to, $trust_root);
}
+ /**
+ * Given an array of CGI data from PHP, this method replaces
+ * "openid_" with "openid." in the CGI key strings (NOT the
+ * values). This is to work around the fact that PHP will mangle
+ * the CGI key strings to protect against register_globals
+ * problems.
+ */
function fixResponse($arr)
{
// Depending on PHP settings, the query data received may have
@@ -293,6 +447,48 @@ class Net_OpenID_Consumer {
return $result;
}
+ /**
+ * This method is called to interpret the server's response to an
+ * OpenID request. It is called in Step 4 of the flow described
+ * in the overview.
+ *
+ * The return value is a pair, consisting of a status and
+ * additional information. The status values are strings, but
+ * should be referred to by their symbolic values:
+ * $Net_OpenID_SUCCESS, $Net_OpenID_FAILURE, and
+ * $Net_OpenID_SETUP_NEEDED.
+ *
+ * When $Net_OpenID_SUCCESS is returned, the additional
+ * information returned is either null or a string. If it is
+ * null, it means the user cancelled the login, and no further
+ * information can be determined. If the additional information
+ * is a string, it is the identity that has been verified as
+ * belonging to the user making this request.
+ *
+ * When $Net_OpenID_FAILURE is returned, the additional
+ * information is either null or a string. In either case, this
+ * code means that the identity verification failed. If it can be
+ * determined, the identity that failed to verify is returned.
+ * Otherwise null is returned.
+ *
+ * When $Net_OpenID_SETUP_NEEDED is returned, the additional
+ * information is the user setup URL. This is a URL returned only
+ * as a response to requests made with openid.mode=immediate,
+ * which indicates that the login was unable to proceed, and the
+ * user should be sent to that URL if they wish to proceed with
+ * the login.
+ *
+ * @param string $token This is the token for this authentication
+ * transaction, generated by the call to beginAuth.
+ *
+ * @param array $query This is a dictionary-like object containing
+ * the query parameters the OpenID server included in its redirect
+ * back to the return_to URL. The keys and values should both be
+ * url-unescaped.
+ *
+ * @return array $array Returns the status of the response and any
+ * additional information, as described above.
+ */
function completeAuth($token, $query)
{
global $Net_OpenID_SUCCESS, $Net_OpenID_FAILURE;
@@ -318,6 +514,9 @@ class Net_OpenID_Consumer {
}
}
+ /**
+ * @access private
+ */
function _gotIdentityInfo($consumer_id, $server_id, $server_url)
{
global $Net_OpenID_SUCCESS, $_Net_OpenID_NONCE_CHRS,
@@ -333,6 +532,9 @@ class Net_OpenID_Consumer {
$server_url, $nonce));
}
+ /**
+ * @access private
+ */
function _constructRedirect($assoc, $auth_req, $return_to, $trust_root)
{
$redir_args = array(
@@ -351,6 +553,9 @@ class Net_OpenID_Consumer {
$redir_args));
}
+ /**
+ * @access private
+ */
function _doIdRes($token, $query)
{
global $Net_OpenID_FAILURE, $Net_OpenID_SETUP_NEEDED,
@@ -418,6 +623,9 @@ class Net_OpenID_Consumer {
return array($Net_OpenID_SUCCESS, $consumer_id);
}
+ /**
+ * @access private
+ */
function _checkAuth($nonce, $query, $server_url)
{
global $Net_OpenID_FAILURE, $Net_OpenID_SUCCESS;
@@ -477,6 +685,9 @@ class Net_OpenID_Consumer {
return $Net_OpenID_FAILURE;
}
+ /**
+ * @access private
+ */
function _getAssociation($server_url, $replace = false)
{
global $_Net_OpenID_TOKEN_LIFETIME;
@@ -498,6 +709,9 @@ class Net_OpenID_Consumer {
return $assoc;
}
+ /**
+ * @access private
+ */
function _genToken($nonce, $consumer_id, $server_id, $server_url)
{
$timestamp = strval(time());
@@ -511,6 +725,9 @@ class Net_OpenID_Consumer {
return Net_OpenID_toBase64($sig . $joined);
}
+ /**
+ * @access private
+ */
function _splitToken($token)
{
global $_Net_OpenID_TOKEN_LIFETIME;
@@ -544,6 +761,9 @@ class Net_OpenID_Consumer {
return array_slice($split, 1);
}
+ /**
+ * @access private
+ */
function _findIdentityInfo($identity_url)
{
global $Net_OpenID_HTTP_FAILURE;
@@ -564,6 +784,9 @@ class Net_OpenID_Consumer {
return $this->_parseIdentityInfo($data, $consumer_id);
}
+ /**
+ * @access private
+ */
function _parseIdentityInfo($data, $consumer_id)
{
global $Net_OpenID_PARSE_ERROR, $Net_OpenID_SUCCESS;
@@ -593,6 +816,9 @@ class Net_OpenID_Consumer {
return array($Net_OpenID_SUCCESS, $normalized);
}
+ /**
+ * @access private
+ */
function _createAssociateRequest($dh, $args = null)
{
global $_Net_OpenID_DEFAULT_MOD, $_Net_OpenID_DEFAULT_GEN;
@@ -624,6 +850,9 @@ class Net_OpenID_Consumer {
return Net_OpenID_http_build_query($args);
}
+ /**
+ * @access private
+ */
function _fetchAssociation($dh, $server_url, $body)
{
$ret = $this->fetcher->post($server_url, $body);
@@ -653,6 +882,9 @@ class Net_OpenID_Consumer {
return $this->_parseAssociation($results, $dh, $server_url);
}
+ /**
+ * @access private
+ */
function _parseAssociation($results, $dh, $server_url)
{
$required_keys = array('assoc_type', 'assoc_handle',
@@ -707,6 +939,26 @@ class Net_OpenID_Consumer {
}
}
+/**
+ * This class represents an in-progress OpenID authentication request.
+ * It exists to make transferring information between the beginAuth
+ * and constructRedirect methods easier. Users of the OpenID consumer
+ * library will need to be aware of the $token value, and may care
+ * about the $server_url value. All other fields are internal
+ * information for the library which the user of the library shouldn't
+ * touch at all.
+ *
+ * The 'token' is the token generated by the library. It must be
+ * saved until the user's return request, via whatever mechanism works
+ * best for this consumer application.
+ *
+ * The 'server_url' is the URL of the identity server that will be
+ * used. It isn't necessary to do anything with this value, but it is
+ * available for consumers that wish to either blacklist or whitelist
+ * OpenID servers.
+ *
+ * @package OpenID
+ */
class Net_OpenID_AuthRequest {
function Net_OpenID_AuthRequest($token, $server_id, $server_url, $nonce)
{