This plan outlines a possible method of integrating social login, 2 factor authentication, and also the option for a developer to introduce their own authentication methods through their own sprinkles.
For every authentication method, there will be an authenticator class, which will have standard methods depending on what type of authenticator it is (see below). Each authenticator will be enabled in the config file. This is also where any application credentials that are needed by the authenticator will also be stored.
The presence of it in the configuration will then allow UserFrosting to "register" the authenticator class in a sub container called authenticators. They have been set up in the config so that multiple instances of the same authenticator class can be used, such as if a person had two standard oath2 sites they wanted to use.
The different authenticator types will be split up into sub-containers again depending on what type it is.
- Primary - Uses standard username/password form
- External - Requires user input/redirect through another website
- Secondary - Any 2nd Factor Authentication
This mode will use the standard username/password form. Each plugin will have a priority, so that the plugin with the highest priority will be tried first, and the one with the second highest will be tried second and so on. The priority will probably be set by the order in which they come in the config file.
This allows for other login sources to be used, such as LDAP.
This plugin will be based on the PrimaryAuthenticator class
This sort of plugin requires the user to login through another website or a popup, typically through OAuth or OpenID
This plugin will be based on the ExternalAuthenticator class
Possible options:
https://packagist.org/packages/simplesamlphp/simplesamlphp
https://github.com/Adldap2/Adldap2 | http://adldap2.github.io/Adldap2/
https://github.com/dapphp/radius
https://hybridauth.github.io/documentation.html
This is any 2nd Factor authentication. If 2nd Factor authentication is required by an account, when a user logs in they can select any one of the methods that they have set up. They could include:
- Time Based Code Generator
- A list of 'Backup' codes
- A text message with a code.
- U2F token (if possible)
This plugin will be based on the SecondaryAuthenticator class
Possible options:
https://github.com/scheb/two-factor-bundle
https://github.com/paragonie/multi_factor
Each authenticator class will have standard methods, depending on what type it is.
The authenticator classes will also have to manage changing account details etc. It may be nescerary to have seperate account handlers as well, so that if a person wants to use their own oauth server, they can implement it with their own api. An avatar provider class may also have to be implemented with this. (Ref #620)
For the external authenticator class, a method will be needed to get a path for a twig template with a login button (e.g. a Login with Facebook button), and for the secondary authenticator then a method will be needed to render an additional login page.
A standard HybridAuthAuthenticator might be useful which can be extended for each provider supported by HybridAuth.
The different plugins can be enabled or disabled by the configuration, along with any other additional options. As UF uses different configuration files for development and production, it would allow for a developer to more easily use "sandbox credentials" whilst developing.
| Config Name | Type | Description |
|---|---|---|
| slug | String | Name in the container and in the database |
| class_name | String | The full path to the class to use |
| options | Array | Any additional options needed by the specific authenticator |
The configuration will look something like this:
{
"authenticators" : {
"plugin_type" : [
{
"__comment" : "The item defined first will have the highest priority"
},
{
"slug" : "slug_name",
"class_name" : "UserFrosting\\Sprinkle\\ExampleSprinkle\\Authenticators\\PluginType\\AuthenticatorClassName",
"options" : {
"option1" : "Additional Settings Go Here"
}
}
]
}
}
}{
"authenticators" : {
"primary" : [
{
"slug" : "database",
"class_name" : "DatabaseAuthenticator"
},
{
"slug" : "ldap",
"class_name" : "UserFrosting\\Sprinkle\\ExampleSprinkle\\Authenticator\\Primary\\LDAPAuthenticator",
"options" : {
"account_suffix" : "@example.com",
"domain_controllers" : [
"dc1.example.com",
"dc2.example.com"
],
"admin_username" : "",
"admin_password" : ""
}
}
],
"external" : [
{
"slug" : "github",
"class_name" : "UserFrosting\\Sprinkle\\ExampleSprinkle\\Authenticator\\External\\GithubAuthenticator",
"options" : {
"app_id" : "A App ID",
"app_secret" : "Some secret....."
}
}
],
"secondary" : [
{
"slug" : "google_time_code",
"class_name" : "UserFrosting\\Sprinkle\\ExampleSprinkle\\Authenticator\\Secondary\\GoogleTimeCodeAuthenticator",
"options" : {
"salt" : "AKHD3425..."
}
}
]
}
}
}If there is no primary or external authentication configuration set, then it will use a "built-in" configuration for using the passwords in the database. It might be worth making the default uf authentication method mandatory after all of the other primary authenticators have been tried.
| Name | Comment |
|---|---|
| auth_methods | Contains all of the available authentication methods |
| account_auth_method | Associates an account with a authentication method |
| Name | Type | Comments |
|---|---|---|
| id | integer | Auto Increment, Primary Key |
| slug | String |
The config will be used to generate all of the rows in the auth_method table, maybe through another bakery command which also runs on setup.
| Name | Type | Comments |
|---|---|---|
| id | Int | Auto Increment, Primary Key |
| account_id | Int | Links to accounts.id |
| auth_method_id | Int | Links to auth_methods.id |
| options | TEXT | Any credentials needed - In JSON format |
Using JSON in a database is a bit crude - I don't know whether it would be worth to go the extra mile and do like a account_auth_method_options table instead.