first commit
This commit is contained in:
92
plugins/simplesaml/lib/docs/simplesamlphp-authsource.md
Normal file
92
plugins/simplesaml/lib/docs/simplesamlphp-authsource.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Creating authentication sources
|
||||
|
||||
All authentication sources are located in the `src/Auth/Source/` directory in a module, and the class name is `\SimpleSAML\Module\<module>\Auth\Source\<name>`.
|
||||
The authentication source must extend the `\SimpleSAML\Auth\Source` class or one of its subclasses.
|
||||
|
||||
The "entry point" of an authentication source is the `authenticate()`-function.
|
||||
Once that function is called, the authentication module can do whatever it wishes to do.
|
||||
There are only two requirements:
|
||||
|
||||
- Never show any pages to the user directly from within the `authenticate()`-function.
|
||||
(This will lead to problems if the user decides to reload the page.)
|
||||
|
||||
- Return control to SimpleSAMLphp after authenticating the user.
|
||||
If the module is able to authenticate the user without doing any redirects, it should just update the state-array and return.
|
||||
If the module does a redirect, it must call `\SimpleSAML\Auth\Source::completeAuth()` with the updated state array.
|
||||
|
||||
Everything else is up to the module.
|
||||
If the module needs to redirect the user, for example because it needs to show the user a page asking for credentials, it needs to save the state array.
|
||||
For that we have the `\SimpleSAML\Auth\State` class.
|
||||
This is only a convenience class, and you are not required to use it (but its use is encouraged, since it handles some potential pitfalls).
|
||||
|
||||
## Saving state
|
||||
|
||||
The `\SimpleSAML\Auth\State` class has two functions that you should use:
|
||||
`saveState($state, $stage)`, and `loadState($id, $stage)`.
|
||||
The `$stage` parameter must be an unique identifier for the current position in the authentication.
|
||||
It is used to prevent a malicious user from taking a state you save in one location, and give it to a different location.
|
||||
|
||||
The `saveState()`-function returns an id, which you should pass to the `loadState()`-function later.
|
||||
|
||||
## Username/password authentication
|
||||
|
||||
Since username/password authentication is quite a common operation, a base class has been created for this.
|
||||
This is the `\SimpleSAML\Module\core\Auth\UserPassBase` class, which is can be found as `modules/core/lib/Auth/UserPassBase.php`.
|
||||
|
||||
The only function you need to implement is the `login($username, $password)`-function.
|
||||
This function receives the username and password the user entered, and is expected to return the attributes of that user.
|
||||
If the username or password is incorrect, it should throw an error saying so:
|
||||
|
||||
throw new \SimpleSAML\Error\Error(\SimpleSAML\Error\ErrorCodes::WRONGUSERPASS);
|
||||
|
||||
"[Implementing custom username/password authentication](./simplesamlphp-customauth)" describes how to implement username/password authentication using that base class.
|
||||
|
||||
## Generic rules & requirements
|
||||
|
||||
- Must be derived from the `\SimpleSAML\Auth\Source`-class.
|
||||
|
||||
**Rationale**:
|
||||
- Deriving all authentication sources from a single base class allows us extend all authentication sources by extending the base class.
|
||||
|
||||
- If a constructor is implemented, it must first call the parent constructor, passing along all parameters, before accessing any of the parameters.
|
||||
In general, only the $config parameter should be accessed when implementing the authentication source.
|
||||
|
||||
**Rationale**:
|
||||
- PHP doesn't automatically call any parent constructor, so it needs to be done manually.
|
||||
- The `$info`-array is used to provide information to the `\SimpleSAML\Auth\Source` base class, and therefore needs to be included.
|
||||
- Including the `$config`-array makes it possible to add generic configuration options that are valid for all authentication sources.
|
||||
|
||||
- The `authenticate(array &$state)`-function must be implemented.
|
||||
If this function completes, it is assumed that the user is authenticated, and that the `$state`-array has been updated with the user's attributes.
|
||||
|
||||
**Rationale**:
|
||||
- Allowing the `authenticate()`-function to return after updating the `$state`-array enables us to do authentication without redirecting the user.
|
||||
This can be used if the authentication doesn't require user input, for example if the authentication can be done based on the IP-address of the user.
|
||||
|
||||
- If the `authenticate`-function does not return, it must at a later time call `\SimpleSAML\Auth\Source::completeAuth` with the new state array.
|
||||
The state array must be an update of the array passed to the `authenticate`-function.
|
||||
|
||||
**Rationale**:
|
||||
- Preserving the same state array allows us to save information in that array before the authentication starts, and restoring it when authentication completes.
|
||||
|
||||
- No pages may be shown to the user from the `authenticate()`-function.
|
||||
Instead, the state should be saved, and the user should be redirected to a new page.
|
||||
|
||||
**Rationale**:
|
||||
- The `authenticate()`-function is called in the context of a different PHP page.
|
||||
If the user reloads that page, unpredictable results may occur.
|
||||
|
||||
- No state information about any authentication should be stored in the authentication source object.
|
||||
It must instead be stored in the state array.
|
||||
Any changes to variables in the authentication source object may be lost.
|
||||
|
||||
**Rationale**:
|
||||
- This saves us from having to save the entire authentication object between requests.
|
||||
Instead, we can recreate it from the configuration.
|
||||
|
||||
- The authentication source object must be serializable.
|
||||
It may be serialized between being constructed and the call to the `authenticate()`-function.
|
||||
This means that, for example, no database connections should be created in the constructor and later used in the `authenticate()`-function.
|
||||
|
||||
**Rationale**:
|
||||
- If parsing the configuration and creating the authentication object is shown to be a bottleneck, we can cache an initialized authentication source.
|
Reference in New Issue
Block a user