Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Trust and Identity Incubator
Test_IdP
Commits
82164e5c
Commit
82164e5c
authored
Jun 25, 2021
by
Martin van Es
Browse files
Add customauth module and idp-hosted changes
parent
06e3ff28
Changes
18
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
82164e5c
# Test_IdP
# Test_IdP
metadata/saml20-idp-hosted.php
```
$metadata['__DYNAMIC:1__'] = [
+ 'auth' => 'custom-userpass',
```
config/authsources.php
```
+ 'custom-userpass' => [
+ 'customauth:External',
+ ],
```
metadata/saml20-idp-hosted.php
View file @
82164e5c
...
@@ -63,28 +63,46 @@ $metadata['__DYNAMIC:1__'] = [
...
@@ -63,28 +63,46 @@ $metadata['__DYNAMIC:1__'] = [
],
],
// X.509 key and certificate. Relative to the cert directory.
// X.509 key and certificate. Relative to the cert directory.
'privatekey'
=>
'server.
pem
'
,
'privatekey'
=>
'server.
key
'
,
'certificate'
=>
'server.crt'
,
'certificate'
=>
'server.crt'
,
/*
/*
* Authentication source to use. Must be one that is configured in
* Authentication source to use. Must be one that is configured in
* 'config/authsources.php'.
* 'config/authsources.php'.
*/
*/
'auth'
=>
'example-userpass'
,
'auth'
=>
'custom-userpass'
,
//'auth' => 'example-userpass',
/* Uncomment the following to use the uri NameFormat on attributes. */
/* Uncomment the following to use the uri NameFormat on attributes. */
/
*
/
/'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
'authproc'
=>
[
'authproc'
=>
[
// Convert LDAP names to oids.
5
=>
[
100 => ['class' => 'core:AttributeMap', 'name2oid'],
'class'
=>
'core:TargetedID'
,
'identifyingAttribute'
=>
'eduPersonTargetedId'
,
'nameId'
=>
TRUE
,
],
8
=>
[
'class'
=>
'core:PHP'
,
'code'
=>
'
unset($attributes["eduPersonTargetedId"]);
'
,
],
// Convert LDAP names to urn.
10
=>
[
'class'
=>
'core:AttributeMap'
,
'name2oid'
],
],
],
*/
'attributes.NameFormat'
=>
'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
,
'attributeencodings'
=>
array
(
'urn:oid:1.3.6.1.4.1.5923.1.1.1.10'
=>
'raw'
,
/* eduPersonTargetedID with oid NameFormat. */
),
];
];
$query
=
"select o.name, o.type, c.value from idps i
$query
=
"select o.name, o.type, c.value from idps i
lef
t join config c on c.idp_id = i.idp_id
righ
t join config c on c.idp_id = i.idp_id
lef
t join options o on c.option_id = o.option_id
righ
t join options o on c.option_id = o.option_id
where i.host = :host"
;
where i.host = :host"
;
...
@@ -97,7 +115,7 @@ foreach ($result as $row) {
...
@@ -97,7 +115,7 @@ foreach ($result as $row) {
$name
=
explode
(
':'
,
$row
[
'name'
]);
$name
=
explode
(
':'
,
$row
[
'name'
]);
$value
=
$row
[
'value'
];
$value
=
$row
[
'value'
];
$config
=
array_merge_recursive
(
$config
,
nest
(
$name
,
$value
));
$config
=
array_merge_recursive
(
$config
,
nest
(
$name
,
$value
));
}
}
$metadata
[
'__DYNAMIC:1__'
]
=
array_replace_recursive
(
$metadata
[
'__DYNAMIC:1__'
],
$config
);
$metadata
[
'__DYNAMIC:1__'
]
=
array_replace_recursive
(
$metadata
[
'__DYNAMIC:1__'
],
$config
);
modules/customauth/.gitignore
0 → 100644
View file @
82164e5c
enable
modules/customauth/README.md
0 → 100644
View file @
82164e5c
# simplesamlphp-module-customauth
CustomAuth simpleSAML php auth source
modules/customauth/default-disable
0 → 100644
View file @
82164e5c
This file indicates that the default state of this module
is disabled. To enable, create a file named enable in the
same directory as this file.
modules/customauth/lib/Auth/Process/RedirectTest.php
0 → 100644
View file @
82164e5c
<?php
declare
(
strict_types
=
1
);
namespace
SimpleSAML\Module\customauth\Auth\Process
;
use
SimpleSAML\Auth
;
use
SimpleSAML\Module
;
use
SimpleSAML\Utils
;
/**
* A simple processing filter for testing that redirection works as it should.
*
*/
class
RedirectTest
extends
\
SimpleSAML\Auth\ProcessingFilter
{
/**
* Initialize processing of the redirect test.
*
* @param array &$state The state we should update.
* @return void
*/
public
function
process
(
&
$state
)
{
assert
(
is_array
(
$state
));
assert
(
array_key_exists
(
'Attributes'
,
$state
));
// To check whether the state is saved correctly
$state
[
'Attributes'
][
'RedirectTest1'
]
=
[
'OK'
];
// Save state and redirect
$id
=
Auth\State
::
saveState
(
$state
,
'customauth:redirectfilter-test'
);
$url
=
Module
::
getModuleURL
(
'customauth/redirecttest.php'
);
Utils\HTTP
::
redirectTrustedURL
(
$url
,
[
'StateId'
=>
$id
]);
}
}
modules/customauth/lib/Auth/Source/External.php
0 → 100644
View file @
82164e5c
<?php
declare
(
strict_types
=
1
);
namespace
SimpleSAML\Module\customauth\Auth\Source
;
use
SimpleSAML\Auth
;
use
SimpleSAML\Error
;
use
SimpleSAML\Module
;
use
SimpleSAML\Utils
;
/**
* Example external authentication source.
*
* This class is an custom authentication source which is designed to
* hook into an external authentication system.
*
* To adapt this to your own web site, you should:
* 1. Create your own module directory.
* 2. Add a file "default-enable" to that directory.
* 3. Copy this file and modules/customauth/www/resume.php to their corresponding
* location in the new module.
* 4. Replace all occurrences of "customauth" in this file and in resume.php with the name of your module.
* 5. Adapt the getUser()-function, the authenticate()-function and the logout()-function to your site.
* 6. Add an entry in config/authsources.php referencing your module. E.g.:
* 'myauth' => array(
* '<mymodule>:External',
* ),
*
* @package SimpleSAMLphp
*/
class
External
extends
\
SimpleSAML\Auth\Source
{
/**
* The key of the AuthId field in the state.
*/
public
const
AUTHID
=
'SimpleSAML\Module\customauth\Auth\Source\External.AuthId'
;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public
function
__construct
(
$info
,
$config
)
{
assert
(
is_array
(
$info
));
assert
(
is_array
(
$config
));
// Call the parent constructor first, as required by the interface
parent
::
__construct
(
$info
,
$config
);
// Do any other configuration we need here
}
/**
* Retrieve attributes for the user.
*
* @return array|null The user's attributes, or NULL if the user isn't authenticated.
*/
private
function
getUser
():
?array
{
/*
* In this example we assume that the attributes are
* stored in the users PHP session, but this could be replaced
* with anything.
*/
if
(
!
session_id
())
{
// session_start not called before. Do it here
session_start
();
}
/*
* Find the attributes for the user.
* Note that all attributes in SimpleSAMLphp are multivalued, so we need
* to store them as arrays.
*/
$attributes
=
null
;
if
(
isset
(
$_SESSION
[
'attributes'
]))
foreach
(
$_SESSION
[
'attributes'
]
as
$key
=>
$value
)
{
#$attributes[$key] = array_filter(array_map('trim', explode(',', $value)));
$attributes
[
$key
]
=
is_array
(
$value
)
?
$value
:
[
$value
];
}
return
$attributes
;
}
/**
* Log in using an external authentication helper.
*
* @param array &$state Information about the current authentication.
* @return void
*/
public
function
authenticate
(
&
$state
)
{
assert
(
is_array
(
$state
));
$attributes
=
$this
->
getUser
();
if
(
$attributes
!==
null
)
{
/*
* The user is already authenticated.
*
* Add the users attributes to the $state-array, and return control
* to the authentication process.
*/
$state
[
'Attributes'
]
=
$attributes
;
return
;
}
/*
* The user isn't authenticated. We therefore need to
* send the user to the login page.
*/
/*
* First we add the identifier of this authentication source
* to the state array, so that we know where to resume.
*/
$state
[
'customauth:AuthID'
]
=
$this
->
authId
;
/*
* We need to save the $state-array, so that we can resume the
* login process after authentication.
*
* Note the second parameter to the saveState-function. This is a
* unique identifier for where the state was saved, and must be used
* again when we retrieve the state.
*
* The reason for it is to prevent
* attacks where the user takes a $state-array saved in one location
* and restores it in another location, and thus bypasses steps in
* the authentication process.
*/
$stateId
=
Auth\State
::
saveState
(
$state
,
'customauth:External'
);
/*
* Now we generate a URL the user should return to after authentication.
* We assume that whatever authentication page we send the user to has an
* option to return the user to a specific page afterwards.
*/
$returnTo
=
Module
::
getModuleURL
(
'customauth/resume.php'
,
[
'State'
=>
$stateId
,
]);
/*
* Get the URL of the authentication page.
*
* Here we use the getModuleURL function again, since the authentication page
* is also part of this module, but in a real example, this would likely be
* the absolute URL of the login page for the site.
*/
$authPage
=
Module
::
getModuleURL
(
'customauth/authpage.php'
);
/*
* The redirect to the authentication page.
*
* Note the 'ReturnTo' parameter. This must most likely be replaced with
* the real name of the parameter for the login page.
*/
Utils\HTTP
::
redirectTrustedURL
(
$authPage
,
[
'ReturnTo'
=>
$returnTo
,
]);
/*
* The redirect function never returns, so we never get this far.
*/
assert
(
false
);
}
/**
* Resume authentication process.
*
* This function resumes the authentication process after the user has
* entered his or her credentials.
*
* @return void
* @throws \SimpleSAML\Error\BadRequest
* @throws \SimpleSAML\Error\Exception
*/
public
static
function
resume
()
{
/*
* First we need to restore the $state-array. We should have the identifier for
* it in the 'State' request parameter.
*/
if
(
!
isset
(
$_REQUEST
[
'State'
]))
{
throw
new
Error\BadRequest
(
'Missing "State" parameter.'
);
}
/*
* Once again, note the second parameter to the loadState function. This must
* match the string we used in the saveState-call above.
*/
/** @var array $state */
$state
=
Auth\State
::
loadState
(
$_REQUEST
[
'State'
],
'customauth:External'
);
/*
* Raise SAML Error Response when the 'Create SAML Error Response'
* checkbox was checked
*/
if
(
isset
(
$_SESSION
[
'ErrorResponse'
]))
{
unset
(
$_SESSION
[
'ErrorResponse'
]);
Auth\State
::
throwException
(
$state
,
new
\
SimpleSAML\Module\saml\Error
(
\
SAML2\Constants
::
STATUS_RESPONDER
,
\
SAML2\Constants
::
STATUS_AUTHN_FAILED
,
'Authentication failed'
)
);
}
/*
* Now we have the $state-array, and can use it to locate the authentication
* source.
*/
$source
=
Auth\Source
::
getById
(
$state
[
'customauth:AuthID'
]);
if
(
$source
===
null
)
{
/*
* The only way this should fail is if we remove or rename the authentication source
* while the user is at the login page.
*/
throw
new
Error\Exception
(
'Could not find authentication source with id '
.
$state
[
self
::
AUTHID
]);
}
/*
* Make sure that we haven't switched the source type while the
* user was at the authentication page. This can only happen if we
* change config/authsources.php while an user is logging in.
*/
if
(
!
(
$source
instanceof
self
))
{
throw
new
Error\Exception
(
'Authentication source type changed.'
);
}
/*
* OK, now we know that our current state is sane. Time to actually log the user in.
*
* First we check that the user is acutally logged in, and didn't simply skip the login page.
*/
$attributes
=
$source
->
getUser
();
if
(
$attributes
===
null
)
{
/*
* The user isn't authenticated.
*
* Here we simply throw an exception, but we could also redirect the user back to the
* login page.
*/
throw
new
Error\Exception
(
'User not authenticated after login page.'
);
}
/*
* So, we have a valid user. Time to resume the authentication process where we
* paused it in the authenticate()-function above.
*/
$state
[
'Attributes'
]
=
$attributes
;
Auth\Source
::
completeAuth
(
$state
);
/*
* The completeAuth-function never returns, so we never get this far.
*/
assert
(
false
);
}
/**
* This function is called when the user start a logout operation, for example
* by logging out of a SP that supports single logout.
*
* @param array &$state The logout state array.
* @return void
*/
public
function
logout
(
&
$state
)
{
assert
(
is_array
(
$state
));
if
(
!
session_id
())
{
// session_start not called before. Do it here
session_start
();
}
/*
* In this example we simply remove the 'uid' from the session.
*/
unset
(
$_SESSION
[
'attributes'
]);
/*
* If we need to do a redirect to a different page, we could do this
* here, but in this example we don't need to do this.
*/
}
}
modules/customauth/lib/Auth/Source/StaticSource.php
0 → 100644
View file @
82164e5c
<?php
declare
(
strict_types
=
1
);
namespace
SimpleSAML\Module\customauth\Auth\Source
;
use
SimpleSAML\Utils
;
/**
* Example authentication source.
*
* This class is an example authentication source which will always return a user with
* a static set of attributes.
*
* @author Olav Morken, UNINETT AS.
* @package SimpleSAMLphp
*/
class
StaticSource
extends
\
SimpleSAML\Auth\Source
{
/**
* The attributes we return.
* @var array
*/
private
$attributes
;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public
function
__construct
(
$info
,
$config
)
{
assert
(
is_array
(
$info
));
assert
(
is_array
(
$config
));
// Call the parent constructor first, as required by the interface
parent
::
__construct
(
$info
,
$config
);
// Parse attributes
try
{
$this
->
attributes
=
Utils\Attributes
::
normalizeAttributesArray
(
$config
);
}
catch
(
\
Exception
$e
)
{
throw
new
\
Exception
(
'Invalid attributes for authentication source '
.
$this
->
authId
.
': '
.
$e
->
getMessage
());
}
}
/**
* Log in using static attributes.
*
* @param array &$state Information about the current authentication.
* @return void
*/
public
function
authenticate
(
&
$state
)
{
assert
(
is_array
(
$state
));
$state
[
'Attributes'
]
=
$this
->
attributes
;
}
}
modules/customauth/lib/Auth/Source/UserPass.php
0 → 100644
View file @
82164e5c
<?php
declare
(
strict_types
=
1
);
namespace
SimpleSAML\Module\customauth\Auth\Source
;
use
SimpleSAML\Error
;
use
SimpleSAML\Utils
;
/**
* Example authentication source - username & password.
*
* This class is an example authentication source which stores all username/passwords in an array,
* and authenticates users against this array.
*
* @author Olav Morken, UNINETT AS.
* @package SimpleSAMLphp
*/
class
UserPass
extends
\
SimpleSAML\Module\core\Auth\UserPassBase
{
/**
* Our users, stored in an associative array. The key of the array is "<username>:<password>",
* while the value of each element is a new array with the attributes for each user.
*
* @var array
*/
private
$users
;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public
function
__construct
(
$info
,
$config
)
{
assert
(
is_array
(
$info
));
assert
(
is_array
(
$config
));
// Call the parent constructor first, as required by the interface
parent
::
__construct
(
$info
,
$config
);
$this
->
users
=
[];
// Validate and parse our configuration
foreach
(
$config
as
$userpass
=>
$attributes
)
{
if
(
!
is_string
(
$userpass
))
{
throw
new
\
Exception
(
'Invalid <username>:<password> for authentication source '
.
$this
->
authId
.
': '
.
$userpass
);
}
$userpass
=
explode
(
':'
,
$userpass
,
2
);
if
(
count
(
$userpass
)
!==
2
)
{
throw
new
\
Exception
(
'Invalid <username>:<password> for authentication source '
.
$this
->
authId
.
': '
.
$userpass
[
0
]
);
}
$username
=
$userpass
[
0
];
$password
=
$userpass
[
1
];
try
{
$attributes
=
Utils\Attributes
::
normalizeAttributesArray
(
$attributes
);
}
catch
(
\
Exception
$e
)
{
throw
new
\
Exception
(
'Invalid attributes for user '
.
$username
.
' in authentication source '
.
$this
->
authId
.
': '
.
$e
->
getMessage
());
}
$this
->
users
[
$username
.
':'
.
$password
]
=
$attributes
;
}
}
/**
* Attempt to log in using the given username and password.
*
* On a successful login, this function should return the users attributes. On failure,
* it should throw an exception. If the error was caused by the user entering the wrong
* username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
*
* Note that both the username and the password are UTF-8 encoded.
*
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
* @return array Associative array with the users attributes.
*/
protected
function
login
(
$username
,
$password
)
{
assert
(
is_string
(
$username
));
assert
(
is_string
(
$password
));
$userpass
=
$username
.
':'
.
$password
;
if
(
!
array_key_exists
(
$userpass
,
$this
->
users
))
{
throw
new
Error\Error
(
'WRONGUSERPASS'
);
}
return
$this
->
users
[
$userpass
];
}
}
modules/customauth/templates/authenticate.tpl.bak
0 → 100644
View file @
82164e5c
<!DOCTYPE html>
<html>
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=utf-8"
>