diff options
author | tailor <cygnus@janrain.com> | 2006-01-13 23:44:45 +0000 |
---|---|---|
committer | tailor <cygnus@janrain.com> | 2006-01-13 23:44:45 +0000 |
commit | 3a09110c51b51ca2728993508d124162e2f966db (patch) | |
tree | 430af15623253397337b0be2896e35e0ec649b64 /Net | |
parent | db97dc546fe67ee18b404a9f26762a68ca7c4797 (diff) | |
download | php-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.php | 310 |
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) { |