ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
Auth_OpenID_GenericConsumer Class Reference
+ Collaboration diagram for Auth_OpenID_GenericConsumer:

Public Member Functions

 Auth_OpenID_GenericConsumer ($store)
 This method initializes a new Auth_OpenID_Consumer instance to access the library.
 begin ($service_endpoint)
 Called to begin OpenID authentication using the specified Auth_OpenID_ServiceEndpoint.
 complete ($message, $endpoint, $return_to)
 Given an Auth_OpenID_Message, Auth_OpenID_ServiceEndpoint and optional return_to URL, complete OpenID authentication.
 _completeInvalid ($message, $endpoint, $unused)
 private
 _complete_cancel ($message, $endpoint, $unused)
 private
 _complete_error ($message, $endpoint, $unused)
 private
 _complete_setup_needed ($message, $endpoint, $unused)
 private
 _complete_id_res ($message, $endpoint, $return_to)
 private
 _checkSetupNeeded ($message)
 private
 _doIdRes ($message, $endpoint, $return_to)
 private
 _checkReturnTo ($message, $return_to)
 private
 _verifyReturnToArgs ($query)
 private
 _idResCheckSignature ($message, $server_url)
 private
 _verifyDiscoveryResults ($message, $endpoint=null)
 private
 _verifyDiscoveryResultsOpenID1 ($message, $endpoint)
 private
 _verifyDiscoverySingle ($endpoint, $to_match)
 private
 _verifyDiscoveryResultsOpenID2 ($message, $endpoint)
 private
 _discoverAndVerify ($claimed_id, $to_match_endpoints)
 private
 _verifyDiscoveryServices ($claimed_id, $services, $to_match_endpoints)
 private
 _idResGetNonceOpenID1 ($message, $endpoint)
 Extract the nonce from an OpenID 1 response.
 _idResCheckNonce ($message, $endpoint)
 private
 _idResCheckForFields ($message)
 private
 _checkAuth ($message, $server_url)
 private
 _createCheckAuthRequest ($message)
 private
 _processCheckAuthResponse ($response, $server_url)
 private
 _makeKVPost ($message, $server_url)
 private
 _getAssociation ($endpoint)
 private
 _extractSupportedAssociationType ($server_error, $endpoint, $assoc_type)
 Handle ServerErrors resulting from association requests.
 _negotiateAssociation ($endpoint)
 private
 _requestAssociation ($endpoint, $assoc_type, $session_type)
 private
 _extractAssociation ($assoc_response, $assoc_session)
 private
 _createAssociateRequest ($endpoint, $assoc_type, $session_type)
 private
 _getOpenID1SessionType ($assoc_response)
 Given an association response message, extract the OpenID 1.X session type.

Static Public Member Functions

static _httpResponseToMessage ($response, $server_url)
 Adapt a POST response to a Message.

Data Fields

 $discoverMethod = 'Auth_OpenID_discover'
 private
 $store
 This consumer's store object.
 $_use_assocs
 private
 $openid1_nonce_query_arg_name = 'janrain_nonce'
 private
 $openid1_return_to_identifier_name = 'openid1_claimed_id'
 Another query parameter that gets added to the return_to for OpenID 1; if the user's session state is lost, use this claimed identifier to do discovery when verifying the response.

Detailed Description

Definition at line 568 of file Consumer.php.

Member Function Documentation

Auth_OpenID_GenericConsumer::_checkAuth (   $message,
  $server_url 
)

private

Definition at line 1334 of file Consumer.php.

References _createCheckAuthRequest(), _makeKVPost(), and _processCheckAuthResponse().

Referenced by _idResCheckSignature().

{
$request = $this->_createCheckAuthRequest($message);
if ($request === null) {
return false;
}
$resp_message = $this->_makeKVPost($request, $server_url);
if (($resp_message === null) ||
(is_a($resp_message, 'Auth_OpenID_ServerErrorContainer'))) {
return false;
}
return $this->_processCheckAuthResponse($resp_message, $server_url);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_checkReturnTo (   $message,
  $return_to 
)

private

Definition at line 813 of file Consumer.php.

References $result, _verifyReturnToArgs(), Auth_OpenID\arrayGet(), Auth_OpenID_OPENID_NS, Auth_OpenID_urinorm(), and Auth_OpenID\isFailure().

Referenced by _doIdRes().

{
// Check an OpenID message and its openid.return_to value
// against a return_to URL from an application. Return True
// on success, False on failure.
// Check the openid.return_to args against args in the
// original message.
$message->toPostArgs());
return false;
}
// Check the return_to base URL against the one in the
// message.
$msg_return_to = $message->getArg(Auth_OpenID_OPENID_NS,
'return_to');
if (Auth_OpenID::isFailure($return_to)) {
// XXX log me
return false;
}
$return_to_parts = parse_url(Auth_OpenID_urinorm($return_to));
$msg_return_to_parts = parse_url(Auth_OpenID_urinorm($msg_return_to));
// If port is absent from both, add it so it's equal in the
// check below.
if ((!array_key_exists('port', $return_to_parts)) &&
(!array_key_exists('port', $msg_return_to_parts))) {
$return_to_parts['port'] = null;
$msg_return_to_parts['port'] = null;
}
// If path is absent from both, add it so it's equal in the
// check below.
if ((!array_key_exists('path', $return_to_parts)) &&
(!array_key_exists('path', $msg_return_to_parts))) {
$return_to_parts['path'] = null;
$msg_return_to_parts['path'] = null;
}
// The URL scheme, authority, and path MUST be the same
// between the two URLs.
foreach (array('scheme', 'host', 'port', 'path') as $component) {
// If the url component is absent in either URL, fail.
// There should always be a scheme, host, port, and path.
if (!array_key_exists($component, $return_to_parts)) {
return false;
}
if (!array_key_exists($component, $msg_return_to_parts)) {
return false;
}
if (Auth_OpenID::arrayGet($return_to_parts, $component) !==
Auth_OpenID::arrayGet($msg_return_to_parts, $component)) {
return false;
}
}
return true;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_checkSetupNeeded (   $message)

private

Definition at line 738 of file Consumer.php.

References Auth_OpenID_OPENID1_NS.

Referenced by _complete_id_res().

{
// In OpenID 1, we check to see if this is a cancel from
// immediate mode by the presence of the user_setup_url
// parameter.
if ($message->isOpenID1()) {
$user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
'user_setup_url');
if ($user_setup_url !== null) {
return true;
}
}
return false;
}

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_complete_cancel (   $message,
  $endpoint,
  $unused 
)

private

Definition at line 687 of file Consumer.php.

{
return new Auth_OpenID_CancelResponse($endpoint);
}
Auth_OpenID_GenericConsumer::_complete_error (   $message,
  $endpoint,
  $unused 
)

private

Definition at line 695 of file Consumer.php.

References Auth_OpenID_OPENID_NS.

{
$error = $message->getArg(Auth_OpenID_OPENID_NS, 'error');
$contact = $message->getArg(Auth_OpenID_OPENID_NS, 'contact');
$reference = $message->getArg(Auth_OpenID_OPENID_NS, 'reference');
return new Auth_OpenID_FailureResponse($endpoint, $error,
$contact, $reference);
}
Auth_OpenID_GenericConsumer::_complete_id_res (   $message,
  $endpoint,
  $return_to 
)

private

Definition at line 722 of file Consumer.php.

References _checkSetupNeeded(), _doIdRes(), and Auth_OpenID_OPENID1_NS.

{
$user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
'user_setup_url');
if ($this->_checkSetupNeeded($message)) {
$endpoint, $user_setup_url);
} else {
return $this->_doIdRes($message, $endpoint, $return_to);
}
}

+ Here is the call graph for this function:

Auth_OpenID_GenericConsumer::_complete_setup_needed (   $message,
  $endpoint,
  $unused 
)

private

Definition at line 708 of file Consumer.php.

References _completeInvalid(), and Auth_OpenID_OPENID2_NS.

{
if (!$message->isOpenID2()) {
return $this->_completeInvalid($message, $endpoint);
}
$user_setup_url = $message->getArg(Auth_OpenID_OPENID2_NS,
'user_setup_url');
return new Auth_OpenID_SetupNeededResponse($endpoint, $user_setup_url);
}

+ Here is the call graph for this function:

Auth_OpenID_GenericConsumer::_completeInvalid (   $message,
  $endpoint,
  $unused 
)

private

Definition at line 675 of file Consumer.php.

References Auth_OpenID_OPENID_NS.

Referenced by _complete_setup_needed().

{
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
'<No mode set>');
return new Auth_OpenID_FailureResponse($endpoint,
sprintf("Invalid openid.mode '%s'", $mode));
}

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_createAssociateRequest (   $endpoint,
  $assoc_type,
  $session_type 
)

private

Definition at line 1661 of file Consumer.php.

References Auth_OpenID_OPENID2_NS, and Auth_OpenID_Message\fromOpenIDArgs().

Referenced by _requestAssociation().

{
if (array_key_exists($session_type, $this->session_types)) {
$session_type_class = $this->session_types[$session_type];
if (is_callable($session_type_class)) {
$assoc_session = $session_type_class();
} else {
$assoc_session = new $session_type_class();
}
} else {
return null;
}
$args = array(
'mode' => 'associate',
'assoc_type' => $assoc_type);
if (!$endpoint->compatibilityMode()) {
$args['ns'] = Auth_OpenID_OPENID2_NS;
}
// Leave out the session type if we're in compatibility mode
// *and* it's no-encryption.
if ((!$endpoint->compatibilityMode()) ||
($assoc_session->session_type != 'no-encryption')) {
$args['session_type'] = $assoc_session->session_type;
}
$args = array_merge($args, $assoc_session->getRequest());
return array($assoc_session, $message);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_createCheckAuthRequest (   $message)

private

Definition at line 1353 of file Consumer.php.

References Auth_OpenID_OPENID_NS.

Referenced by _checkAuth().

{
$signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
if ($signed) {
foreach (explode(',', $signed) as $k) {
$value = $message->getAliasedArg($k);
if ($value === null) {
return null;
}
}
}
$ca_message = $message->copy();
$ca_message->setArg(Auth_OpenID_OPENID_NS, 'mode',
'check_authentication');
return $ca_message;
}

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_discoverAndVerify (   $claimed_id,
  $to_match_endpoints 
)

private

Definition at line 1179 of file Consumer.php.

References _verifyDiscoveryServices().

Referenced by _verifyDiscoveryResultsOpenID1(), and _verifyDiscoveryResultsOpenID2().

{
// oidutil.log('Performing discovery on %s' % (claimed_id,))
list($unused, $services) = call_user_func($this->discoverMethod,
$claimed_id,
$this->fetcher); // fixed php 5.4 compatability
if (!$services) {
return new Auth_OpenID_FailureResponse(null,
sprintf("No OpenID information found at %s",
$claimed_id));
}
return $this->_verifyDiscoveryServices($claimed_id, $services,
$to_match_endpoints);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_doIdRes (   $message,
  $endpoint,
  $return_to 
)

private

Definition at line 757 of file Consumer.php.

References $result, _checkReturnTo(), _idResCheckForFields(), _idResCheckNonce(), _idResCheckSignature(), _verifyDiscoveryResults(), Auth_OpenID\addPrefix(), Auth_OpenID_NO_DEFAULT, Auth_OpenID_OPENID_NS, and Auth_OpenID\isFailure().

Referenced by _complete_id_res().

{
// Checks for presence of appropriate fields (and checks
// signed list fields)
$result = $this->_idResCheckForFields($message);
return $result;
}
if (!$this->_checkReturnTo($message, $return_to)) {
return new Auth_OpenID_FailureResponse(null,
sprintf("return_to does not match return URL. Expected %s, got %s",
$return_to,
$message->getArg(Auth_OpenID_OPENID_NS, 'return_to')));
}
// Verify discovery information:
$result = $this->_verifyDiscoveryResults($message, $endpoint);
return $result;
}
$endpoint = $result;
$result = $this->_idResCheckSignature($message,
$endpoint->server_url);
return $result;
}
$result = $this->_idResCheckNonce($message, $endpoint);
return $result;
}
$signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, 'signed',
if (Auth_OpenID::isFailure($signed_list_str)) {
return $signed_list_str;
}
$signed_list = explode(',', $signed_list_str);
$signed_fields = Auth_OpenID::addPrefix($signed_list, "openid.");
return new Auth_OpenID_SuccessResponse($endpoint, $message,
$signed_fields);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_extractAssociation (   $assoc_response,
  $assoc_session 
)

private

Definition at line 1569 of file Consumer.php.

References _getOpenID1SessionType(), Auth_OpenID_NO_DEFAULT, Auth_OpenID_OPENID2_NS, Auth_OpenID_OPENID_NS, Auth_OpenID_Association\fromExpiresIn(), Auth_OpenID\intval(), and Auth_OpenID\isFailure().

Referenced by _requestAssociation().

{
// Extract the common fields from the response, raising an
// exception if they are not found
$assoc_type = $assoc_response->getArg(
Auth_OpenID_OPENID_NS, 'assoc_type',
if (Auth_OpenID::isFailure($assoc_type)) {
return $assoc_type;
}
$assoc_handle = $assoc_response->getArg(
Auth_OpenID_OPENID_NS, 'assoc_handle',
if (Auth_OpenID::isFailure($assoc_handle)) {
return $assoc_handle;
}
// expires_in is a base-10 string. The Python parsing will
// accept literals that have whitespace around them and will
// accept negative values. Neither of these are really in-spec,
// but we think it's OK to accept them.
$expires_in_str = $assoc_response->getArg(
Auth_OpenID_OPENID_NS, 'expires_in',
if (Auth_OpenID::isFailure($expires_in_str)) {
return $expires_in_str;
}
$expires_in = Auth_OpenID::intval($expires_in_str);
if ($expires_in === false) {
$err = sprintf("Could not parse expires_in from association ".
"response %s", print_r($assoc_response, true));
return new Auth_OpenID_FailureResponse(null, $err);
}
// OpenID 1 has funny association session behaviour.
if ($assoc_response->isOpenID1()) {
$session_type = $this->_getOpenID1SessionType($assoc_response);
} else {
$session_type = $assoc_response->getArg(
Auth_OpenID_OPENID2_NS, 'session_type',
if (Auth_OpenID::isFailure($session_type)) {
return $session_type;
}
}
// Session type mismatch
if ($assoc_session->session_type != $session_type) {
if ($assoc_response->isOpenID1() &&
($session_type == 'no-encryption')) {
// In OpenID 1, any association request can result in
// a 'no-encryption' association response. Setting
// assoc_session to a new no-encryption session should
// make the rest of this function work properly for
// that case.
$assoc_session = new Auth_OpenID_PlainTextConsumerSession();
} else {
// Any other mismatch, regardless of protocol version
// results in the failure of the association session
// altogether.
return null;
}
}
// Make sure assoc_type is valid for session_type
if (!in_array($assoc_type, $assoc_session->allowed_assoc_types)) {
return null;
}
// Delegate to the association session to extract the secret
// from the response, however is appropriate for that session
// type.
$secret = $assoc_session->extractSecret($assoc_response);
if ($secret === null) {
return null;
}
$expires_in, $assoc_handle, $secret, $assoc_type);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_extractSupportedAssociationType (   $server_error,
  $endpoint,
  $assoc_type 
)

Handle ServerErrors resulting from association requests.

Returns
$result If server replied with an C{unsupported-type} error, return a tuple of supported C{association_type}, C{session_type}. Otherwise logs the error and returns null.

private

Definition at line 1464 of file Consumer.php.

References Auth_OpenID_OPENID_NS.

Referenced by _negotiateAssociation().

{
// Any error message whose code is not 'unsupported-type'
// should be considered a total failure.
if (($server_error->error_code != 'unsupported-type') ||
($server_error->message->isOpenID1())) {
return null;
}
// The server didn't like the association/session type that we
// sent, and it sent us back a message that might tell us how
// to handle it.
// Extract the session_type and assoc_type from the error
// message
$assoc_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS,
'assoc_type');
$session_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS,
'session_type');
if (($assoc_type === null) || ($session_type === null)) {
return null;
} else if (!$this->negotiator->isAllowed($assoc_type,
$session_type)) {
return null;
} else {
return array($assoc_type, $session_type);
}
}

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_getAssociation (   $endpoint)

private

Definition at line 1433 of file Consumer.php.

References _negotiateAssociation().

Referenced by begin().

{
if (!$this->_use_assocs) {
return null;
}
$assoc = $this->store->getAssociation($endpoint->server_url);
if (($assoc === null) ||
($assoc->getExpiresIn() <= 0)) {
$assoc = $this->_negotiateAssociation($endpoint);
if ($assoc !== null) {
$this->store->storeAssociation($endpoint->server_url,
$assoc);
}
}
return $assoc;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_getOpenID1SessionType (   $assoc_response)

Given an association response message, extract the OpenID 1.X session type.

This function mostly takes care of the 'no-encryption' default behavior in OpenID 1.

If the association type is plain-text, this function will return 'no-encryption'

private

Returns
$typ The association type for this message

Definition at line 1708 of file Consumer.php.

References Auth_OpenID_OPENID1_NS.

Referenced by _extractAssociation().

{
// If it's an OpenID 1 message, allow session_type to default
// to None (which signifies "no-encryption")
$session_type = $assoc_response->getArg(Auth_OpenID_OPENID1_NS,
'session_type');
// Handle the differences between no-encryption association
// respones in OpenID 1 and 2:
// no-encryption is not really a valid session type for OpenID
// 1, but we'll accept it anyway, while issuing a warning.
if ($session_type == 'no-encryption') {
// oidutil.log('WARNING: OpenID server sent "no-encryption"'
// 'for OpenID 1.X')
} else if (($session_type == '') || ($session_type === null)) {
// Missing or empty session type is the way to flag a
// 'no-encryption' response. Change the session type to
// 'no-encryption' so that it can be handled in the same
// way as OpenID 2 'no-encryption' respones.
$session_type = 'no-encryption';
}
return $session_type;
}

+ Here is the caller graph for this function:

static Auth_OpenID_GenericConsumer::_httpResponseToMessage (   $response,
  $server_url 
)
static

Adapt a POST response to a Message.

Parameters
$responseResult of a POST to an OpenID endpoint.

private

Definition at line 1400 of file Consumer.php.

References Auth_OpenID_Message\fromKVForm(), and Auth_OpenID_ServerErrorContainer\fromMessage().

Referenced by _makeKVPost().

{
// Should this function be named Message.fromHTTPResponse instead?
$response_message = Auth_OpenID_Message::fromKVForm($response->body);
if ($response->status == 400) {
$response_message);
} else if ($response->status != 200 and $response->status != 206) {
return null;
}
return $response_message;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_idResCheckForFields (   $message)

private

Definition at line 1281 of file Consumer.php.

References Auth_OpenID_NO_DEFAULT, Auth_OpenID_OPENID1_NS, Auth_OpenID_OPENID2_NS, Auth_OpenID_OPENID_NS, and Auth_OpenID\isFailure().

Referenced by _doIdRes().

{
$basic_fields = array('return_to', 'assoc_handle', 'sig', 'signed');
$basic_sig_fields = array('return_to', 'identity');
$require_fields = array(
Auth_OpenID_OPENID2_NS => array_merge($basic_fields,
array('op_endpoint')),
Auth_OpenID_OPENID1_NS => array_merge($basic_fields,
array('identity'))
);
$require_sigs = array(
Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields,
array('response_nonce',
'claimed_id',
'assoc_handle',
'op_endpoint')),
Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields,
array('nonce'))
);
foreach ($require_fields[$message->getOpenIDNamespace()] as $field) {
if (!$message->hasKey(Auth_OpenID_OPENID_NS, $field)) {
return new Auth_OpenID_FailureResponse(null,
"Missing required field '".$field."'");
}
}
$signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS,
'signed',
if (Auth_OpenID::isFailure($signed_list_str)) {
return $signed_list_str;
}
$signed_list = explode(',', $signed_list_str);
foreach ($require_sigs[$message->getOpenIDNamespace()] as $field) {
// Field is present and not in signed list
if ($message->hasKey(Auth_OpenID_OPENID_NS, $field) &&
(!in_array($field, $signed_list))) {
return new Auth_OpenID_FailureResponse(null,
"'".$field."' not signed");
}
}
return null;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_idResCheckNonce (   $message,
  $endpoint 
)

private

Definition at line 1243 of file Consumer.php.

References $timestamp, _idResGetNonceOpenID1(), Auth_OpenID_OPENID2_NS, and Auth_OpenID_splitNonce().

Referenced by _doIdRes().

{
if ($message->isOpenID1()) {
// This indicates that the nonce was generated by the consumer
$nonce = $this->_idResGetNonceOpenID1($message, $endpoint);
$server_url = '';
} else {
$nonce = $message->getArg(Auth_OpenID_OPENID2_NS,
'response_nonce');
$server_url = $endpoint->server_url;
}
if ($nonce === null) {
return new Auth_OpenID_FailureResponse($endpoint,
"Nonce missing from response");
}
$parts = Auth_OpenID_splitNonce($nonce);
if ($parts === null) {
return new Auth_OpenID_FailureResponse($endpoint,
"Malformed nonce in response");
}
list($timestamp, $salt) = $parts;
if (!$this->store->useNonce($server_url, $timestamp, $salt)) {
return new Auth_OpenID_FailureResponse($endpoint,
"Nonce already used or out of range");
}
return null;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_idResCheckSignature (   $message,
  $server_url 
)

private

Definition at line 937 of file Consumer.php.

References _checkAuth(), Auth_OpenID_OPENID_NS, and Auth_OpenID\isFailure().

Referenced by _doIdRes().

{
$assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS,
'assoc_handle');
if (Auth_OpenID::isFailure($assoc_handle)) {
return $assoc_handle;
}
$assoc = $this->store->getAssociation($server_url, $assoc_handle);
if ($assoc) {
if ($assoc->getExpiresIn() <= 0) {
// XXX: It might be a good idea sometimes to re-start
// the authentication with a new association. Doing it
// automatically opens the possibility for
// denial-of-service by a server that just returns
// expired associations (or really short-lived
// associations)
return new Auth_OpenID_FailureResponse(null,
'Association with ' . $server_url . ' expired');
}
if (!$assoc->checkMessageSignature($message)) {
return new Auth_OpenID_FailureResponse(null,
"Bad signature");
}
} else {
// It's not an association we know about. Stateless mode
// is our only possible path for recovery. XXX - async
// framework will not want to block on this call to
// _checkAuth.
if (!$this->_checkAuth($message, $server_url)) {
return new Auth_OpenID_FailureResponse(null,
"Server denied check_authentication");
}
}
return null;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_idResGetNonceOpenID1 (   $message,
  $endpoint 
)

Extract the nonce from an OpenID 1 response.

Return the nonce from the BARE_NS since we independently check the return_to arguments are the same as those in the response message.

See the openid1_nonce_query_arg_name class variable

Returns
$nonce The nonce as a string or null

private

Definition at line 1234 of file Consumer.php.

References Auth_OpenID_BARE_NS.

Referenced by _idResCheckNonce().

{
return $message->getArg(Auth_OpenID_BARE_NS,
$this->openid1_nonce_query_arg_name);
}

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_makeKVPost (   $message,
  $server_url 
)

private

Definition at line 1418 of file Consumer.php.

References _httpResponseToMessage().

Referenced by _checkAuth(), and _requestAssociation().

{
$body = $message->toURLEncoded();
$resp = $this->fetcher->post($server_url, $body);
if ($resp === null) {
return null;
}
return $this->_httpResponseToMessage($resp, $server_url);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_negotiateAssociation (   $endpoint)

private

Definition at line 1499 of file Consumer.php.

References _extractSupportedAssociationType(), _requestAssociation(), and Auth_OpenID\isFailure().

Referenced by _getAssociation().

{
// Get our preferred session/association type from the negotiatior.
list($assoc_type, $session_type) = $this->negotiator->getAllowedType();
$assoc = $this->_requestAssociation(
$endpoint, $assoc_type, $session_type);
if (Auth_OpenID::isFailure($assoc)) {
return null;
}
if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) {
$why = $assoc;
$supportedTypes = $this->_extractSupportedAssociationType(
$why, $endpoint, $assoc_type);
if ($supportedTypes !== null) {
list($assoc_type, $session_type) = $supportedTypes;
// Attempt to create an association from the assoc_type
// and session_type that the server told us it
// supported.
$assoc = $this->_requestAssociation(
$endpoint, $assoc_type, $session_type);
if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) {
// Do not keep trying, since it rejected the
// association type that it told us to use.
// oidutil.log('Server %s refused its suggested association
// 'type: session_type=%s, assoc_type=%s'
// % (endpoint.server_url, session_type,
// assoc_type))
return null;
} else {
return $assoc;
}
} else {
return null;
}
} else {
return $assoc;
}
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_processCheckAuthResponse (   $response,
  $server_url 
)

private

Definition at line 1373 of file Consumer.php.

References Auth_OpenID_OPENID_NS.

Referenced by _checkAuth().

{
$is_valid = $response->getArg(Auth_OpenID_OPENID_NS, 'is_valid',
'false');
$invalidate_handle = $response->getArg(Auth_OpenID_OPENID_NS,
'invalidate_handle');
if ($invalidate_handle !== null) {
$this->store->removeAssociation($server_url,
$invalidate_handle);
}
if ($is_valid == 'true') {
return true;
}
return false;
}

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_requestAssociation (   $endpoint,
  $assoc_type,
  $session_type 
)

private

Definition at line 1548 of file Consumer.php.

References _createAssociateRequest(), _extractAssociation(), and _makeKVPost().

Referenced by _negotiateAssociation().

{
list($assoc_session, $args) = $this->_createAssociateRequest(
$endpoint, $assoc_type, $session_type);
$response_message = $this->_makeKVPost($args, $endpoint->server_url);
if ($response_message === null) {
// oidutil.log('openid.associate request failed: %s' % (why[0],))
return null;
} else if (is_a($response_message,
'Auth_OpenID_ServerErrorContainer')) {
return $response_message;
}
return $this->_extractAssociation($response_message, $assoc_session);
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_verifyDiscoveryResults (   $message,
  $endpoint = null 
)

private

Definition at line 980 of file Consumer.php.

References _verifyDiscoveryResultsOpenID1(), _verifyDiscoveryResultsOpenID2(), and Auth_OpenID_OPENID2_NS.

Referenced by _doIdRes().

{
if ($message->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS) {
return $this->_verifyDiscoveryResultsOpenID2($message,
$endpoint);
} else {
return $this->_verifyDiscoveryResultsOpenID1($message,
$endpoint);
}
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_verifyDiscoveryResultsOpenID1 (   $message,
  $endpoint 
)

private

Definition at line 994 of file Consumer.php.

References $result, _discoverAndVerify(), _verifyDiscoverySingle(), Auth_OpenID_BARE_NS, Auth_OpenID_OPENID1_NS, Auth_OpenID_TYPE_1_0, Auth_OpenID_TYPE_1_1, and Auth_OpenID\isFailure().

Referenced by _verifyDiscoveryResults().

{
$claimed_id = $message->getArg(Auth_OpenID_BARE_NS,
$this->openid1_return_to_identifier_name);
if (($endpoint === null) && ($claimed_id === null)) {
return new Auth_OpenID_FailureResponse($endpoint,
'When using OpenID 1, the claimed ID must be supplied, ' .
'either by passing it through as a return_to parameter ' .
'or by using a session, and supplied to the GenericConsumer ' .
'as the argument to complete()');
} else if (($endpoint !== null) && ($claimed_id === null)) {
$claimed_id = $endpoint->claimed_id;
}
$to_match = new Auth_OpenID_ServiceEndpoint();
$to_match->type_uris = array(Auth_OpenID_TYPE_1_1);
$to_match->local_id = $message->getArg(Auth_OpenID_OPENID1_NS,
'identity');
// Restore delegate information from the initiation phase
$to_match->claimed_id = $claimed_id;
if ($to_match->local_id === null) {
return new Auth_OpenID_FailureResponse($endpoint,
"Missing required field openid.identity");
}
$to_match_1_0 = $to_match->copy();
$to_match_1_0->type_uris = array(Auth_OpenID_TYPE_1_0);
if ($endpoint !== null) {
$result = $this->_verifyDiscoverySingle($endpoint, $to_match);
if (is_a($result, 'Auth_OpenID_TypeURIMismatch')) {
$result = $this->_verifyDiscoverySingle($endpoint,
$to_match_1_0);
}
// oidutil.log("Error attempting to use stored
// discovery information: " + str(e))
// oidutil.log("Attempting discovery to
// verify endpoint")
} else {
return $endpoint;
}
}
// Endpoint is either bad (failed verification) or None
return $this->_discoverAndVerify($to_match->claimed_id,
array($to_match, $to_match_1_0));
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_verifyDiscoveryResultsOpenID2 (   $message,
  $endpoint 
)

private

Definition at line 1103 of file Consumer.php.

References $result, _discoverAndVerify(), _verifyDiscoverySingle(), Auth_OpenID_OPENID2_NS, Auth_OpenID_TYPE_2_0, Auth_OpenID_ServiceEndpoint\fromOPEndpointURL(), and Auth_OpenID\isFailure().

Referenced by _verifyDiscoveryResults().

{
$to_match = new Auth_OpenID_ServiceEndpoint();
$to_match->type_uris = array(Auth_OpenID_TYPE_2_0);
$to_match->claimed_id = $message->getArg(Auth_OpenID_OPENID2_NS,
'claimed_id');
$to_match->local_id = $message->getArg(Auth_OpenID_OPENID2_NS,
'identity');
$to_match->server_url = $message->getArg(Auth_OpenID_OPENID2_NS,
'op_endpoint');
if ($to_match->server_url === null) {
return new Auth_OpenID_FailureResponse($endpoint,
"OP Endpoint URL missing");
}
// claimed_id and identifier must both be present or both be
// absent
if (($to_match->claimed_id === null) &&
($to_match->local_id !== null)) {
return new Auth_OpenID_FailureResponse($endpoint,
'openid.identity is present without openid.claimed_id');
}
if (($to_match->claimed_id !== null) &&
($to_match->local_id === null)) {
return new Auth_OpenID_FailureResponse($endpoint,
'openid.claimed_id is present without openid.identity');
}
if ($to_match->claimed_id === null) {
// This is a response without identifiers, so there's
// really no checking that we can do, so return an
// endpoint that's for the specified `openid.op_endpoint'
$to_match->server_url);
}
if (!$endpoint) {
// The claimed ID doesn't match, so we have to do
// discovery again. This covers not using sessions, OP
// identifier endpoints and responses that didn't match
// the original request.
// oidutil.log('No pre-discovered information supplied.')
return $this->_discoverAndVerify($to_match->claimed_id,
array($to_match));
} else {
// The claimed ID matches, so we use the endpoint that we
// discovered in initiation. This should be the most
// common case.
$result = $this->_verifyDiscoverySingle($endpoint, $to_match);
$endpoint = $this->_discoverAndVerify($to_match->claimed_id,
array($to_match));
if (Auth_OpenID::isFailure($endpoint)) {
return $endpoint;
}
}
}
// The endpoint we return should have the claimed ID from the
// message we just verified, fragment and all.
if ($endpoint->claimed_id != $to_match->claimed_id) {
$endpoint->claimed_id = $to_match->claimed_id;
}
return $endpoint;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_verifyDiscoveryServices (   $claimed_id,
  $services,
  $to_match_endpoints 
)

private

Definition at line 1199 of file Consumer.php.

References $result, _verifyDiscoverySingle(), and Auth_OpenID\isFailure().

Referenced by _discoverAndVerify().

{
// Search the services resulting from discovery to find one
// that matches the information from the assertion
foreach ($services as $endpoint) {
foreach ($to_match_endpoints as $to_match_endpoint) {
$result = $this->_verifyDiscoverySingle($endpoint,
$to_match_endpoint);
// It matches, so discover verification has
// succeeded. Return this endpoint.
return $endpoint;
}
}
}
return new Auth_OpenID_FailureResponse(null,
sprintf('No matching endpoint found after discovering %s: %s',
$claimed_id, $result->message));
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_verifyDiscoverySingle (   $endpoint,
  $to_match 
)

private

Definition at line 1051 of file Consumer.php.

References Auth_OpenID_OPENID1_NS, and Auth_OpenID\urldefrag().

Referenced by _verifyDiscoveryResultsOpenID1(), _verifyDiscoveryResultsOpenID2(), and _verifyDiscoveryServices().

{
// Every type URI that's in the to_match endpoint has to be
// present in the discovered endpoint.
foreach ($to_match->type_uris as $type_uri) {
if (!$endpoint->usesExtension($type_uri)) {
return new Auth_OpenID_TypeURIMismatch($endpoint,
"Required type ".$type_uri." not present");
}
}
// Fragments do not influence discovery, so we can't compare a
// claimed identifier with a fragment to discovered
// information.
list($defragged_claimed_id, $_) =
Auth_OpenID::urldefrag($to_match->claimed_id);
if ($defragged_claimed_id != $endpoint->claimed_id) {
return new Auth_OpenID_FailureResponse($endpoint,
sprintf('Claimed ID does not match (different subjects!), ' .
'Expected %s, got %s', $defragged_claimed_id,
$endpoint->claimed_id));
}
if ($to_match->getLocalID() != $endpoint->getLocalID()) {
return new Auth_OpenID_FailureResponse($endpoint,
sprintf('local_id mismatch. Expected %s, got %s',
$to_match->getLocalID(), $endpoint->getLocalID()));
}
// If the server URL is None, this must be an OpenID 1
// response, because op_endpoint is a required parameter in
// OpenID 2. In that case, we don't actually care what the
// discovered server_url is, because signature checking or
// check_auth should take care of that check for us.
if ($to_match->server_url === null) {
if ($to_match->preferredNamespace() != Auth_OpenID_OPENID1_NS) {
return new Auth_OpenID_FailureResponse($endpoint,
"Preferred namespace mismatch (bug)");
}
} else if ($to_match->server_url != $endpoint->server_url) {
return new Auth_OpenID_FailureResponse($endpoint,
sprintf('OP Endpoint mismatch. Expected %s, got %s',
$to_match->server_url, $endpoint->server_url));
}
return null;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::_verifyReturnToArgs (   $query)

private

Definition at line 880 of file Consumer.php.

References $query, Auth_OpenID\arrayGet(), Auth_OpenID_BARE_NS, Auth_OpenID_OPENID_NS, Auth_OpenID_Message\fromPostArgs(), Auth_OpenID\isFailure(), and Auth_OpenID\parse_str().

Referenced by _checkReturnTo().

{
// Verify that the arguments in the return_to URL are present in this
// response.
$return_to = $message->getArg(Auth_OpenID_OPENID_NS, 'return_to');
if (Auth_OpenID::isFailure($return_to)) {
return $return_to;
}
// XXX: this should be checked by _idResCheckForFields
if (!$return_to) {
return new Auth_OpenID_FailureResponse(null,
"Response has no return_to");
}
$parsed_url = parse_url($return_to);
$q = array();
if (array_key_exists('query', $parsed_url)) {
$rt_query = $parsed_url['query'];
$q = Auth_OpenID::parse_str($rt_query);
}
foreach ($q as $rt_key => $rt_value) {
if (!array_key_exists($rt_key, $query)) {
return new Auth_OpenID_FailureResponse(null,
sprintf("return_to parameter %s absent from query", $rt_key));
} else {
$value = $query[$rt_key];
if ($rt_value != $value) {
return new Auth_OpenID_FailureResponse(null,
sprintf("parameter %s value %s does not match " .
"return_to value %s", $rt_key,
$value, $rt_value));
}
}
}
// Make sure all non-OpenID arguments in the response are also
// in the signed return_to.
$bare_args = $message->getArgs(Auth_OpenID_BARE_NS);
foreach ($bare_args as $key => $value) {
if (Auth_OpenID::arrayGet($q, $key) != $value) {
return new Auth_OpenID_FailureResponse(null,
sprintf("Parameter %s = %s not in return_to URL",
$key, $value));
}
}
return true;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_OpenID_GenericConsumer::Auth_OpenID_GenericConsumer (   $store)

This method initializes a new Auth_OpenID_Consumer instance to access the library.

Parameters
Auth_OpenID_OpenIDStore$storeThis must be an object that implements the interface in Auth_OpenID_OpenIDStore. Several concrete implementations are provided, to cover most common use cases. For stores backed by MySQL, PostgreSQL, or SQLite, see the Auth_OpenID_SQLStore class and its sublcasses. For a filesystem-backed store, see the Auth_OpenID_FileStore module. As a last resort, if it isn't possible for the server to store state at all, an instance of Auth_OpenID_DumbStore can be used.
bool$immediateThis 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.

Definition at line 614 of file Consumer.php.

References $store, Auth_OpenID_getAvailableSessionTypes(), Auth_OpenID_getDefaultNegotiator(), and Auth_Yadis_Yadis\getHTTPFetcher().

{
$this->store = $store;
$this->negotiator = Auth_OpenID_getDefaultNegotiator();
$this->_use_assocs = (is_null($this->store) ? false : true);
$this->session_types = Auth_OpenID_getAvailableSessionTypes();
}

+ Here is the call graph for this function:

Auth_OpenID_GenericConsumer::begin (   $service_endpoint)

Called to begin OpenID authentication using the specified Auth_OpenID_ServiceEndpoint.

private

Definition at line 631 of file Consumer.php.

References $openid1_nonce_query_arg_name, $openid1_return_to_identifier_name, _getAssociation(), and Auth_OpenID_mkNonce().

{
$assoc = $this->_getAssociation($service_endpoint);
$r = new Auth_OpenID_AuthRequest($service_endpoint, $assoc);
if ($r->message->isOpenID1()) {
$r->endpoint->claimed_id;
}
return $r;
}

+ Here is the call graph for this function:

Auth_OpenID_GenericConsumer::complete (   $message,
  $endpoint,
  $return_to 
)

Given an Auth_OpenID_Message, Auth_OpenID_ServiceEndpoint and optional return_to URL, complete OpenID authentication.

private

Definition at line 653 of file Consumer.php.

References Auth_OpenID\arrayGet(), and Auth_OpenID_OPENID_NS.

{
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
'<no mode set>');
$mode_methods = array(
'cancel' => '_complete_cancel',
'error' => '_complete_error',
'setup_needed' => '_complete_setup_needed',
'id_res' => '_complete_id_res',
);
$method = Auth_OpenID::arrayGet($mode_methods, $mode,
'_completeInvalid');
return call_user_func_array(array($this, $method),
array($message, &$endpoint, $return_to));
}

+ Here is the call graph for this function:

Field Documentation

Auth_OpenID_GenericConsumer::$_use_assocs

private

Definition at line 582 of file Consumer.php.

Auth_OpenID_GenericConsumer::$discoverMethod = 'Auth_OpenID_discover'

private

Definition at line 572 of file Consumer.php.

Auth_OpenID_GenericConsumer::$openid1_nonce_query_arg_name = 'janrain_nonce'

private

Definition at line 587 of file Consumer.php.

Referenced by begin().

Auth_OpenID_GenericConsumer::$openid1_return_to_identifier_name = 'openid1_claimed_id'

Another query parameter that gets added to the return_to for OpenID 1; if the user's session state is lost, use this claimed identifier to do discovery when verifying the response.

Definition at line 594 of file Consumer.php.

Referenced by begin().

Auth_OpenID_GenericConsumer::$store

This consumer's store object.

Definition at line 577 of file Consumer.php.

Referenced by Auth_OpenID_GenericConsumer().


The documentation for this class was generated from the following file: