Skip to content
Snippets Groups Projects
Unverified Commit 0c07d7bd authored by Simão Martins's avatar Simão Martins Committed by GitHub
Browse files

Filter multiauth authentication sources from SP using AuthnContextClassRef (#1362)


Co-authored-by: default avatarTim van Dijen <tvdijen@gmail.com>
parent 5e72030d
No related branches found
No related tags found
No related merge requests found
......@@ -36,12 +36,14 @@ authentication source:
'es' => 'Entrar usando un SP SAML',
),
'css-class' => 'SAML',
'AuthnContextClassRef' => array('urn:oasis:names:tc:SAML:2.0:ac:classes:SmartcardPKI', 'urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract'),
),
'example-admin' => array(
'text' => array(
'en' => 'Log in using the admin password',
'es' => 'Entrar usando la contraseña de administrador',
),
'AuthnContextClassRef' => 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport',
),
),
),
......@@ -77,7 +79,7 @@ compatible fashion so both cases should work.
Each source in the sources array has a key and a value. As
mentioned above the key is the authsource identifier and the value
is another array with two optional keys: 'text' and 'css-class'.
is another array with optional keys: 'text', 'css-class', 'help', and 'AuthnContextClassRef'.
The text element is another array with localized strings for one
or more languages. These texts will be shown in the selectsource.php
view. Note that you should at least enter the text in the default
......@@ -87,7 +89,14 @@ the &lt;li> element in the selectsource.php view. By default the
authtype of the authsource is used as the css class with colons
replaced by dashes. So in the previous example, the css class used
in the 'example-admin' authentication source would be
'core-AdminPassword'.
'core-AdminPassword'. The help element is another array with localized
strings for one or more languages. These texts will be shown in the
selectsource.php view. The AuthnContextClassRef is either a string or
an array of strings containing [context class ref names](https://docs.oasis-open.org/security/saml/v2.0/saml-authn-context-2.0-os.pdf).
If an SP sets AuthnContextClassRef the list of authsources will be
filtered to only those containing context class refs that are part of the list set by the SP.
If a single authsource results from this filtering the user will be taken directly to the
authentication page for that source, and will never be shown the multiauth select page.
It is possible to add the parameter `source` to the calling URL,
when accessing a service, to allow the user to preselect the
......
......@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SimpleSAML\Module\multiauth\Auth\Source;
use SAML2\Constants;
use Exception;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
......@@ -12,6 +13,7 @@ use SimpleSAML\Error;
use SimpleSAML\Module;
use SimpleSAML\Session;
use SimpleSAML\Utils;
use SimpleSAML\Module\saml\Error\NoAuthnContext;
/**
* Authentication source which let the user chooses among a list of
......@@ -113,11 +115,22 @@ class MultiAuth extends Auth\Source
}
}
$class_ref = [];
if (array_key_exists('AuthnContextClassRef', $info)) {
$ref = $info['AuthnContextClassRef'];
if (is_string($ref)) {
$class_ref = [$ref];
} else {
$class_ref = $ref;
}
}
$this->sources[] = [
'source' => $source,
'text' => $text,
'help' => $help,
'css_class' => $css_class,
'AuthnContextClassRef' => $class_ref,
];
}
}
......@@ -144,6 +157,30 @@ class MultiAuth extends Auth\Source
$state['multiauth:preselect'] = $this->preselect;
}
if (
!is_null($state['saml:RequestedAuthnContext'])
&& array_key_exists('AuthnContextClassRef', $state['saml:RequestedAuthnContext'])
) {
$refs = array_values($state['saml:RequestedAuthnContext']['AuthnContextClassRef']);
$new_sources = [];
foreach ($this->sources as $source) {
if (count(array_intersect($source['AuthnContextClassRef'], $refs)) >= 1) {
$new_sources[] = $source;
}
}
$state[self::SOURCESID] = $new_sources;
$number_of_sources = count($new_sources);
if ($number_of_sources === 0) {
throw new NoAuthnContext(
Constants::STATUS_RESPONDER,
'No authentication sources exist for the requested AuthnContextClassRefs: ' . implode(', ', $refs)
);
} else if ($number_of_sources === 1) {
MultiAuth::delegateAuthentication($new_sources[0]['source'], $state);
}
}
// Save the $state array, so that we can restore if after a redirect
$id = Auth\State::saveState($state, self::STAGEID);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment