Skip to content
Snippets Groups Projects
Commit 8cf292df authored by Olav Morken's avatar Olav Morken
Browse files

saml: Add new filter "ExpectedAuthnContextClassRef".

This filter verifies the authentication context received from the IdP
against a list of allowed values.

Thanks to Gyula Szabó for creating this filter!

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3031 44740490-163a-0410-bde0-09ae8108e29a
parent 4a00ec67
No related branches found
No related tags found
No related merge requests found
...@@ -144,6 +144,7 @@ The following filters are included in the simpleSAMLphp distribution: ...@@ -144,6 +144,7 @@ The following filters are included in the simpleSAMLphp distribution:
- ['expirycheck:ExpiryDate`](./expirycheck:expirycheck): Block access to accounts that have expired. - ['expirycheck:ExpiryDate`](./expirycheck:expirycheck): Block access to accounts that have expired.
- [`preprodwarning:Warning`](./preprodwarning:warning): Warn the user about accessing a test IdP. - [`preprodwarning:Warning`](./preprodwarning:warning): Warn the user about accessing a test IdP.
- [`saml:AttributeNameID`](./saml:nameid): Generate custom NameID with the value of an attribute. - [`saml:AttributeNameID`](./saml:nameid): Generate custom NameID with the value of an attribute.
- [`saml:ExpectedAuthnContextClassRef`](./saml:authproc_expectedauthncontextclassref): Verify the user's authnentication context.
- [`saml:NameIDAttribute`](./saml:nameidattribute): Create an attribute based on the NameID we receive from the IdP. - [`saml:NameIDAttribute`](./saml:nameidattribute): Create an attribute based on the NameID we receive from the IdP.
- [`saml:PersistentNameID`](./saml:nameid): Generate persistent NameID from an attribute. - [`saml:PersistentNameID`](./saml:nameid): Generate persistent NameID from an attribute.
- [`saml:TransientNameID`](./saml:nameid): Generate transient NameID. - [`saml:TransientNameID`](./saml:nameid): Generate transient NameID.
......
{
"header": {
"en": "Wrong authentication context"
},
"description": {
"en": "Your authentication context is not accepted at this service. Probably too weak or not two-factor."
}
}
{
"header": {
"hu": "Elutas\u00edtott azonos\u00edt\u00e1si m\u00f3d"
},
"description": {
"hu": "A m\u00f3d, ahogyan azonos\u00edtott t\u00e9ged a szem\u00e9lyazonoss\u00e1g szolg\u00e1ltat\u00f3d, nem elfogadott enn\u00e9l a szolg\u00e1ltat\u00e1sn\u00e1l. Val\u00f3sz\u00edn\u0171leg t\u00fal gyenge, vagy nem k\u00e9tfaktoros."
}
}
`saml:ExpectedAuthnContextClassRef`
===================
SP side attribute filter for validate AuthnContextClassRef.
This filter check the AuthnContextClassRef in the authnentication response, and accept or deny the access depend on the strength of authentication.
You can list the accepted authentitcation context values in the Service Provider configuration.
If the given AuthnContextClassRef not match of any accepted value, the user redirected to the error page. It's useful to harmonize the SP's requested AuthnContextClassRef (another authproc filter)i, but you can accept more authentication strength level than what you requested.
Examples
--------
'authproc.sp' => array(
91 => array(
'class' => 'saml:ExpectedAuthnContextClassRef',
'accepted' => array(
'urn:oasis:names:tc:SAML:2.0:post:ac:classes:nist-800-63:3',
'urn:oasis:names:tc:SAML:2.0:ac:classes:Password',
),
),
),
<?php
/**
* Attribute filter for validate AuthnContextClassRef
*
* 91 => array(
* 'class' => 'saml:ExpectedAuthnContextClassRef',
* 'accepted' => array(
* 'urn:oasis:names:tc:SAML:2.0:post:ac:classes:nist-800-63:3',
* 'urn:oasis:names:tc:SAML:2.0:ac:classes:Password',
* ),
* ),
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_saml_Auth_Process_ExpectedAuthnContextClassRef extends SimpleSAML_Auth_ProcessingFilter {
/**
* Array of accepted AuthnContextClassRef
* @var array
*/
private $accepted;
/**
* AuthnContextClassRef of the assertion
* @var string
*/
private $AuthnContextClassRef;
/**
* Initialize this filter, parse configuration
*
* @param array $config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct($config, $reserved) {
parent::__construct($config, $reserved);
assert('is_array($config)');
if (empty($config['accepted'])){
SimpleSAML_Logger::error('ExpectedAuthnContextClassRef: Configuration error. There is no accepted AuthnContextClassRef.');
throw new SimpleSAML_Error_Exception('ExpectedAuthnContextClassRef: Configuration error. There is no accepted AuthnContextClassRef.');
}
$this->accepted = $config['accepted'];
}
/**
*
* @param array &$request The current request
*/
public function process(&$request) {
assert('is_array($request)');
assert('array_key_exists("Attributes", $request)');
$this->AuthnContextClassRef = $request['saml:sp:State']['saml:sp:AuthnContext'];
if (! in_array($this->AuthnContextClassRef,$this->accepted)){
$this->unauthorized($request);
}
}
/**
* When the process logic determines that the user is not
* authorized for this service, then forward the user to
* an 403 unauthorized page.
*
* Separated this code into its own method so that child
* classes can override it and change the action. Forward
* thinking in case a "chained" ACL is needed, more complex
* permission logic.
*
* @param array $request
*/
protected function unauthorized(&$request) {
SimpleSAML_Logger::error('ExpectedAuthnContextClassRef: Invalid authentication context: '.$this->AuthnContextClassRef.'. Accepted values are: ' . var_export($this->accepted, TRUE));
$id = SimpleSAML_Auth_State::saveState($request, 'saml:ExpectedAuthnContextClassRef:unauthorized');
$url = SimpleSAML_Module::getModuleURL(
'saml/sp/wrong_authncontextclassref.php');
SimpleSAML_Utilities::redirect($url, array('StateId' => $id));
}
}
<?php
$header = htmlspecialchars($this->t('{saml:wrong_authncontextclassref:header}'));
$description = htmlspecialchars($this->t('{saml:wrong_authncontextclassref:description}'));
$retry = htmlspecialchars($this->t('{saml:wrong_authncontextclassref:retry}'));
$this->data['header'] = $header;
$this->includeAtTemplateBase('includes/header.php');
echo('<h2>' . $header . '</h2>');
echo('<p>' . $description . '</p>');
$this->includeAtTemplateBase('includes/footer.php');
...@@ -149,6 +149,8 @@ $state['saml:sp:NameID'] = $nameId; ...@@ -149,6 +149,8 @@ $state['saml:sp:NameID'] = $nameId;
$state['PersistentAuthData'][] = 'saml:sp:NameID'; $state['PersistentAuthData'][] = 'saml:sp:NameID';
$state['saml:sp:SessionIndex'] = $sessionIndex; $state['saml:sp:SessionIndex'] = $sessionIndex;
$state['PersistentAuthData'][] = 'saml:sp:SessionIndex'; $state['PersistentAuthData'][] = 'saml:sp:SessionIndex';
$state['saml:sp:AuthnContext'] = $assertion->getAuthnContext();
$state['PersistentAuthData'][] = 'saml:sp:AuthnContext';
if (isset($state['SimpleSAML_Auth_Default.ReturnURL'])) { if (isset($state['SimpleSAML_Auth_Default.ReturnURL'])) {
......
<?php
$globalConfig = SimpleSAML_Configuration::getInstance();
$t = new SimpleSAML_XHTML_Template($globalConfig, 'saml:sp/wrong_authncontextclassref.tpl.php');
$t->show();
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