diff --git a/lib/SimpleSAML/Auth/Source.php b/lib/SimpleSAML/Auth/Source.php index d42d3eef3b0617e8e6b28ab86965cf10e7e39fb4..358cd178d720be82c81bce349178dc1eb326b8e2 100644 --- a/lib/SimpleSAML/Auth/Source.php +++ b/lib/SimpleSAML/Auth/Source.php @@ -99,6 +99,26 @@ abstract class SimpleSAML_Auth_Source { abstract public function authenticate(&$state); + /** + * Reauthenticate an user. + * + * This function is called by the IdP to give the authentication source a chance to + * interact with the user even in the case when the user is already authenticated. + * + * @param array &$state Information about the current authentication. + */ + public function reauthenticate(array &$state) { + assert('isset($state["ReturnCallback"])'); + + /* The default implementation just copies over the previous authentication data. */ + $session = SimpleSAML_Session::getInstance(); + $data = $session->getAuthState($this->authId); + foreach ($data as $k => $v) { + $state[$k] = $v; + } + } + + /** * Complete authentication. * diff --git a/lib/SimpleSAML/IdP.php b/lib/SimpleSAML/IdP.php index f974551946e512a27d8b02e832debf6ba86353f6..a8a2d1f6e8883b4f41e2c2c00bf2697b7d8f0640 100644 --- a/lib/SimpleSAML/IdP.php +++ b/lib/SimpleSAML/IdP.php @@ -326,13 +326,36 @@ class SimpleSAML_IdP { throw new SimpleSAML_Error_NoPassive('Passive authentication not supported.'); } - $state['IdPMetadata'] = $this->getConfig()->toArray(); - $state['ReturnCallback'] = array('SimpleSAML_IdP', 'postAuth'); - $this->authSource->login($state); } + /** + * Reuthenticate the user. + * + * This function reauthenticates an user with an existing session. This + * gives the authentication source a chance to do additional work when + * reauthenticating for SSO. + * + * Note: This function is not used when ForceAuthn=true. + * + * @param array &$state The authentication request state. + */ + private function reauthenticate(array &$state) { + + $sourceImpl = $this->authSource->getAuthSource(); + if ($sourceImpl === NULL) { + /* Backwards-compatibility with non-authsource IdP. */ + foreach ($this->authSource->getAuthDataArray() as $k => $v) { + $state[$k] = $v; + } + return; + } + + $sourceImpl->reauthenticate($state); + } + + /** * Process authentication requests. * @@ -362,14 +385,15 @@ class SimpleSAML_IdP { $needAuth = !$this->isAuthenticated(); } + $state['IdPMetadata'] = $this->getConfig()->toArray(); + $state['ReturnCallback'] = array('SimpleSAML_IdP', 'postAuth'); + try { if ($needAuth) { $this->authenticate($state); assert('FALSE'); } else { - foreach ($this->authSource->getAuthDataArray() as $k => $v) { - $state[$k] = $v; - } + $this->reauthenticate($state); } $this->postAuth($state); } catch (SimpleSAML_Error_Exception $e) {