Update auth document (#52)

* Update auth_auth_provider.md

* Update auth_auth_provider.md

* Create auth_auth_module.md

* Update en.json

* Update sidebars.json

* Update auth_auth_module.md

* Update auth_auth_provider.md

* Update auth_auth_module.md

* Update auth_auth_module.md
This commit is contained in:
Jason Hu 2018-08-22 08:19:32 -07:00 committed by Paulus Schoutsen
parent d1e0563d03
commit b77c3f83e1
4 changed files with 81 additions and 6 deletions

55
docs/auth_auth_module.md Normal file
View File

@ -0,0 +1,55 @@
---
title: "Multi-factor Authentication Modules"
---
Multi-factor Authentication Modules are used in conjunction with [Authentication Provider](auth_auth_provider.html) to provide a fully configurable authentication framework. Each MFA module may provide one multi-factor authentication function. User can enable mulitple mfa module, but can only select one module in login process.
## Defining an mfa auth module
> We currently only support built-in mfa auth modules. Support for custom auth modules might arrive in the future.
Multi-facor Auth modules are defined in `homeassistant/auth/mfa_modules/<name of module>.py`. The auth module will need to provide an implementation of the `MultiFactorAuthModule` class.
For an example of a fully implemented auth module, please see [insecure_example.py](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/auth/mfa_modules/insecure_example.py).
Multi-factor Auth modules shall extend the following methods of `MultiFactorAuthModule` class.
| method | Required | Description
| ------ | -------- | -----------
| `@property def input_schema(self)` | Yes | Return a schema defined the user input form.
| `@property def setup_schema(self)` | No | Return a schema defined the setup input form.
| `async def async_setup_user(self, user_id, setup_data)` | Yes | Set up user for use this auth module.
| `async def async_depose_user(self, user_id)` | Yes | Remove user information from this auth module.
| `async def async_is_user_setup(self, user_id)` | Yes | Return whether user is set up.
| `async def async_validation(self, user_id, user_input)` | Yes | Given a user_id and user input, return valiidation result.
## Workflow
To use a MFA auth module, user has to be created first, then call `AuthManager.async_enable_user_mfa` to setup.
> TODO: draw a diagram
User == select auth provider ==> LoginFlow.init == input/validate username/password ==> LoginFlow.finish ==> if user enabled mfa ==> LoginFlow.select_mfa_module ==> LoginFlow.mfa == input/validate MFA code ==> LoginFlow.finish ==> Done
## Configuration example
```yaml
# configuration.xml
homeassistant:
auth_providers:
- type: homeassistant
- type: legacy_api_password
auth_mfa_modules:
- type: totp
- type: insecure_example
users: [{'user_id': 'a_32_bytes_length_user_id', 'pin': '123456'}]
auth:
```
In this example, user will first select from `homeassistant` or `legacy_api_password` auth provider. For `homeassistant` auth provider, user will first input username/password, if that user enabled both `totp` and `insecure_example`, then user need select one auth module, then input Google Authenticator code or input pin code base on the selection.
> insecure_example is only for demo purpose, please do not use it in production.
## Validation session
Not like auth provider, auth module use session to manage the validation. After auth provider validated, mfa module will create a validation session, include an experiation time and user_id from auth provider validate result. Mutli-factor auth moudle will not only verify the user input, and also verify the session is not experied. The validatoin session data storges in login flow instance.

View File

@ -10,15 +10,33 @@ Once an authentication provider has confirmed the identity of a user, it will pa
> We currently only support built-in auth providers. Support for custom auth providers might arrive in the future.
Auth providers are defined in `homeassistant/auth_providers/<name of provider>.py`. The auth provider module will need to provide an implementation of the `AuthProvider` class and contain a credential flow. This flow is what asks user for information and validates it.
Auth providers are defined in `homeassistant/auth/providers/<name of provider>.py`. The auth provider module will need to provide an implementation of the `AuthProvider` class and `LoginFlow` class, it is what asks user for information and validates it base on `data_entry_flow`.
For an example of a fully implemented auth provider, please see [insecure_example.py](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/auth/providers/insecure_example.py).
Auth providers can extend the following methods.
Auth providers shall extend the following methods of `AuthProvider` class.
| method | Required | Description
| ------ | -------- | -----------
| async def async_credential_flow(self) | Yes | Return an instance of the credential flow for a user to identify itself.
| async def async_get_or_create_credentials(self, flow_result) | Yes | Given the result of a credential flow, return a credentials object. This can either be an existing one or a new one.
| async def async_initialize(self) | No | Callback callled once before interacting with the auth provider for the first time.
| async def async_login_flow(self) | Yes | Return an instance of the login flow for a user to identify itself.
| async def async_get_or_create_credentials(self, flow_result) | Yes | Given the result of a login flow, return a credentials object. This can either be an existing one or a new one.
| async def async_user_meta_for_credentials(credentials) | No | Callback called Home Assistant is going to create a user from a Credentials object. Can be used to populate extra fields for the user.
Auth providers shall extend the following methods of `LoginFlow` class.
| method | Required | Description
| ------ | -------- | -----------
| async def async_step_init(self, user_input=None) | Yes | Handle the login form, see more detail in below.
## async_step_init of LoginFlow
> We may change this inteface in near future.
`LoginFlow` extends `data_entry_flow.FlowHandler`. The first step of data entry flow is hard coded as `init`, so each flow has to implement `async_step_init` method. The pattern of `async_step_init` likes following pseudo-code:
```python
async def async_step_init(self, user_input=None):
return self.async_show_form(step_id='init', data_schema='some schema to construct ui form') if user_input is None
return self.async_show_form(step_id='init', errors) if user_input is invalid
return await self.async_finish(username) if user_input is valid
```

View File

@ -18,6 +18,7 @@
"asyncio_working_with_async": "Working with Async",
"auth_api": "Authentication API",
"API": "API",
"auth_auth_module": "Authentication Modules",
"auth_auth_provider": "Authentication Providers",
"auth_index": "Authentication",
"config_entries_config_flow_handler": "Config Flow Handlers",

View File

@ -25,7 +25,8 @@
"Authentication": [
"auth_index",
"auth_api",
"auth_auth_provider"
"auth_auth_provider",
"auth_auth_module"
],
"Configuration.yaml": [
"configuration_yaml_index"