, UNINETT AS. * @package simpleSAMLphp */ class sspmod_openid_Auth_Source_OpenIDConsumer extends SimpleSAML_Auth_Source { /** * Static openid target to use. * * @var string|NULL */ private $target; /** * Custom realm to use. * * @var string|NULL */ private $realm; /** * List of optional attributes. */ private $optionalAttributes; private $optionalAXAttributes; /** * List of required attributes. */ private $requiredAttributes; private $requiredAXAttributes; /** * Validate SReg responses. */ private $validateSReg; /** * List of custom extension args */ private $extensionArgs; /** * Prefer HTTP Redirect over HTML Form Redirection (POST) */ private $preferHttpRedirect; /** * Constructor for this authentication source. * * @param array $info Information about this authentication source. * @param array $config Configuration. */ public function __construct($info, $config) { /* Call the parent constructor first, as required by the interface. */ parent::__construct($info, $config); $cfgParse = SimpleSAML_Configuration::loadFromArray($config, 'Authentication source ' . var_export($this->authId, TRUE)); $this->target = $cfgParse->getString('target', NULL); $this->realm = $cfgParse->getString('realm', NULL); $this->optionalAttributes = $cfgParse->getArray('attributes.optional', array()); $this->requiredAttributes = $cfgParse->getArray('attributes.required', array()); $this->optionalAXAttributes = $cfgParse->getArray('attributes.ax_optional', array()); $this->requiredAXAttributes = $cfgParse->getArray('attributes.ax_required', array()); $this->validateSReg = $cfgParse->getBoolean('sreg.validate',TRUE); $this->extensionArgs = $cfgParse->getArray('extension.args', array()); $this->preferHttpRedirect = $cfgParse->getBoolean('prefer_http_redirect', FALSE); } /** * Initiate authentication. Redirecting the user to the consumer endpoint * with a state Auth ID. * * @param array &$state Information about the current authentication. */ public function authenticate(&$state) { assert('is_array($state)'); $state['openid:AuthId'] = $this->authId; if ($this->target !== NULL) { /* We know our OpenID target URL. Skip the page where we ask for it. */ $this->doAuth($state, $this->target); /* doAuth() never returns. */ assert('FALSE'); } $id = SimpleSAML_Auth_State::saveState($state, 'openid:init'); $url = SimpleSAML_Module::getModuleURL('openid/consumer.php'); SimpleSAML_Utilities::redirectTrustedURL($url, array('AuthState' => $id)); } /** * Retrieve the Auth_OpenID_Consumer instance. * * @param array &$state The state array we are currently working with. * @return Auth_OpenID_Consumer The Auth_OpenID_Consumer instance. */ private function getConsumer(array &$state) { $store = new sspmod_openid_StateStore($state); $session = new sspmod_openid_SessionStore(); return new Auth_OpenID_Consumer($store, $session); } /** * Retrieve the URL we should return to after successful authentication. * * @return string The URL we should return to after successful authentication. */ private function getReturnTo($stateId) { assert('is_string($stateId)'); return SimpleSAML_Module::getModuleURL('openid/linkback.php', array( 'AuthState' => $stateId, )); } /** * Retrieve the trust root for this openid site. * * @return string The trust root. */ private function getTrustRoot() { if (!empty($this->realm)) { return $this->realm; } else { return SimpleSAML_Utilities::selfURLhost(); } } /** * Send an authentication request to the OpenID provider. * * @param array &$state The state array. * @param string $openid The OpenID we should try to authenticate with. */ public function doAuth(array &$state, $openid) { assert('is_string($openid)'); $stateId = SimpleSAML_Auth_State::saveState($state, 'openid:auth'); $consumer = $this->getConsumer($state); // Begin the OpenID authentication process. $auth_request = $consumer->begin($openid); // No auth request means we can't begin OpenID. if (!$auth_request) { throw new SimpleSAML_Error_BadRequest('Not a valid OpenID: ' . var_export($openid, TRUE)); } $sreg_request = Auth_OpenID_SRegRequest::build( $this->requiredAttributes, $this->optionalAttributes ); if ($sreg_request) { $auth_request->addExtension($sreg_request); } // Create attribute request object $ax_attribute = array(); foreach($this->requiredAXAttributes as $attr) { $ax_attribute[] = Auth_OpenID_AX_AttrInfo::make($attr,1,true); } foreach($this->optionalAXAttributes as $attr) { $ax_attribute[] = Auth_OpenID_AX_AttrInfo::make($attr,1,false); } if (count($ax_attribute) > 0) { // Create AX fetch request $ax_request = new Auth_OpenID_AX_FetchRequest; // Add attributes to AX fetch request foreach($ax_attribute as $attr){ $ax_request->add($attr); } // Add AX fetch request to authentication request $auth_request->addExtension($ax_request); } foreach($this->extensionArgs as $ext_ns => $ext_arg) { if (is_array($ext_arg)) { foreach($ext_arg as $ext_key => $ext_value) { $auth_request->addExtensionArg($ext_ns, $ext_key, $ext_value); } } } // Redirect the user to the OpenID server for authentication. // Store the token for this authentication so we can verify the // response. // For OpenID 1, send a redirect. For OpenID 2, use a Javascript form // to send a POST request to the server or use redirect if // prefer_http_redirect is enabled and redirect URL size // is less than 2049 $should_send_redirect = $auth_request->shouldSendRedirect(); if ($this->preferHttpRedirect || $should_send_redirect) { $redirect_url = $auth_request->redirectURL($this->getTrustRoot(), $this->getReturnTo($stateId)); // If the redirect URL can't be built, display an error message. if (Auth_OpenID::isFailure($redirect_url)) { throw new SimpleSAML_Error_AuthSource($this->authId, 'Could not redirect to server: ' . var_export($redirect_url->message, TRUE)); } // For OpenID 2 failover to POST if redirect URL is longer than 2048 if ($should_send_redirect || strlen($redirect_url) <= 2048) { SimpleSAML_Utilities::redirectTrustedURL($redirect_url); assert('FALSE'); } } // Generate form markup and render it. $form_id = 'openid_message'; $form_html = $auth_request->formMarkup($this->getTrustRoot(), $this->getReturnTo($stateId), FALSE, array('id' => $form_id)); // Display an error if the form markup couldn't be generated; otherwise, render the HTML. if (Auth_OpenID::isFailure($form_html)) { throw new SimpleSAML_Error_AuthSource($this->authId, 'Could not redirect to server: ' . var_export($form_html->message, TRUE)); } else { echo '