mirror of
https://github.com/team-alembic/ash_authentication.git
synced 2024-09-20 13:24:20 +12:00
James Harton
7b607896eb
Now any DSL option which allows the configuring of a token lifetime can take _either_ a positive integer in it's previous default unit or a tuple containing a positive integer and a unit. Closes #376. Additionally includes switching the resettable entity to being a singleton since that feature didn't exist when I started.
298 lines
9.9 KiB
Text
298 lines
9.9 KiB
Text
# DSL: AshAuthentication
|
|
|
|
AshAuthentication provides a turn-key authentication solution for folks using
|
|
[Ash](https://www.ash-hq.org/).
|
|
|
|
## Usage
|
|
|
|
This package assumes that you have [Ash](https://ash-hq.org/) installed and
|
|
configured. See the Ash documentation for details.
|
|
|
|
Once installed you can easily add support for authentication by configuring
|
|
the `AshAuthentication` extension on your resource:
|
|
|
|
```elixir
|
|
defmodule MyApp.Accounts.User do
|
|
use Ash.Resource,
|
|
extensions: [AshAuthentication]
|
|
|
|
attributes do
|
|
uuid_primary_key :id
|
|
attribute :email, :ci_string, allow_nil?: false
|
|
attribute :hashed_password, :string, allow_nil?: false, sensitive?: true
|
|
end
|
|
|
|
authentication do
|
|
api MyApp.Accounts
|
|
|
|
strategies do
|
|
password :password do
|
|
identity_field :email
|
|
hashed_password_field :hashed_password
|
|
end
|
|
end
|
|
end
|
|
|
|
identities do
|
|
identity :unique_email, [:email]
|
|
end
|
|
end
|
|
```
|
|
|
|
If you plan on providing authentication via the web, then you will need to
|
|
define a plug using `AshAuthentication.Plug` which builds a `Plug.Router` that
|
|
routes incoming authentication requests to the correct provider and provides
|
|
callbacks for you to manipulate the conn after success or failure.
|
|
|
|
If you're using AshAuthentication with Phoenix, then check out
|
|
[`ash_authentication_phoenix`](https://github.com/team-alembic/ash_authentication_phoenix)
|
|
which provides route helpers, a controller abstraction and LiveView components
|
|
for easy set up.
|
|
|
|
## Authentication Strategies
|
|
|
|
Currently supported strategies:
|
|
|
|
1. `AshAuthentication.Strategy.Password`
|
|
- authenticate users against your local database using a unique identity
|
|
(such as username or email address) and a password.
|
|
2. `AshAuthentication.Strategy.OAuth2`
|
|
- authenticate using local or remote [OAuth 2.0](https://oauth.net/2/)
|
|
compatible services.
|
|
|
|
## Add-ons
|
|
|
|
Add-ons are like strategies, except that they don't actually provide
|
|
authentication - they just provide features adjacent to authentication.
|
|
Current add-ons:
|
|
|
|
1. `AshAuthentication.AddOn.Confirmation`
|
|
- allows you to force the user to confirm changes using a confirmation
|
|
token (eg. sending a confirmation email when a new user registers).
|
|
|
|
## Supervisor
|
|
|
|
Some add-ons or strategies may require processes to be started which manage
|
|
their state over the lifetime of the application (eg periodically deleting
|
|
expired token revocations). Because of this you should add
|
|
`{AshAuthentication.Supervisor, otp_app: :my_app}` to your application's
|
|
supervision tree. See [the Elixir
|
|
docs](https://hexdocs.pm/elixir/Application.html#module-the-application-callback-module)
|
|
for more information.
|
|
|
|
<!--- ash-hq-hide-start --> <!--- -->
|
|
|
|
## DSL Documentation
|
|
|
|
### Index
|
|
|
|
* authentication
|
|
* tokens
|
|
* strategies
|
|
* add_ons
|
|
|
|
### Docs
|
|
|
|
## authentication
|
|
|
|
Configure authentication for this resource
|
|
|
|
* [tokens](#module-tokens)
|
|
* [strategies](#module-strategies)
|
|
* [add_ons](#module-add_ons)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
* `:subject_name` (`t:atom/0`) - The subject name is used anywhere that a short version of your
|
|
resource name is needed, eg:
|
|
- generating token claims,
|
|
- generating routes,
|
|
- form parameter nesting.
|
|
This needs to be unique system-wide and if not set will be inferred
|
|
from the resource name (ie `MyApp.Accounts.User` will have a subject
|
|
name of `user`).
|
|
|
|
* `:api` (`t:atom/0`) - Required. The name of the Ash API to use to access this resource when
|
|
doing anything authenticaiton related.
|
|
|
|
* `:get_by_subject_action_name` (`t:atom/0`) - The name of the read action used to retrieve records.
|
|
Used internally by `AshAuthentication.subject_to_user/2`. If the
|
|
action doesn't exist, one will be generated for you. The default value is `:get_by_subject`.
|
|
|
|
* `:select_for_senders` (list of `t:atom/0`) - A list of fields that we will ensure are selected whenever a sender will be invoked.
|
|
This is useful if using something like `ash_graphql` which by default only selects
|
|
what fields appear in the query, and if you are exposing these actions that way.
|
|
Defaults to `[:email]` if there is an `:email` attribute on the resource, and `[]`
|
|
otherwise.
|
|
|
|
|
|
|
|
|
|
|
|
### tokens
|
|
|
|
Configure JWT settings for this resource
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
* `:enabled?` (`t:boolean/0`) - Should JWTs be generated by this resource? The default value is `false`.
|
|
|
|
* `:store_all_tokens?` (`t:boolean/0`) - Store all tokens in the `token_resource`?
|
|
Some applications need to keep track of all tokens issued to
|
|
any user. This is optional behaviour with `ash_authentication`
|
|
in order to preserve as much performance as possible. The default value is `false`.
|
|
|
|
* `:require_token_presence_for_authentication?` (`t:boolean/0`) - Require a locally-stored token for authentication?
|
|
This inverts the token validation behaviour from requiring that
|
|
tokens are not revoked to requiring any token presented by a
|
|
client to be present in the token resource to be considered
|
|
valid.
|
|
Requires `store_all_tokens?` to be `true`. The default value is `false`.
|
|
|
|
* `:signing_algorithm` (`t:String.t/0`) - The algorithm to use for token signing.
|
|
Available signing algorithms are;
|
|
EdDSA, Ed448ph, Ed448, Ed25519ph, Ed25519, PS512, PS384, PS256, ES512, ES384, ES256, RS512, RS384, RS256, HS512, HS384 and HS256. The default value is `"HS256"`.
|
|
|
|
* `:token_lifetime` - How long a token should be valid.
|
|
Since refresh tokens are not yet supported, you should
|
|
probably set this to a reasonably long time to ensure
|
|
a good user experience.
|
|
You can either provide a tuple with a time unit, or a positive
|
|
integer, in which case the unit is assumed to be hours.
|
|
Defaults to 14 days. The default value is `{14, :days}`.
|
|
|
|
* `:token_resource` - Required. The resource used to store token information.
|
|
If token generation is enabled for this resource, we need a place to
|
|
store information about tokens, such as revocations and in-flight
|
|
confirmations.
|
|
|
|
* `:signing_secret` - The secret used to sign tokens.
|
|
Takes either a module which implements the `AshAuthentication.Secret`
|
|
behaviour, a 2 arity anonymous function or a string.
|
|
See the module documentation for `AshAuthentication.Secret` for more
|
|
information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### strategies
|
|
|
|
Configure authentication strategies on this resource
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### add_ons
|
|
|
|
Additional add-ons related to, but not providing authentication
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!--- ash-hq-hide-stop --> <!--- -->
|
|
|
|
|
|
## authentication
|
|
Configure authentication for this resource
|
|
|
|
### Nested DSLs
|
|
* [tokens](#authentication-tokens)
|
|
* [strategies](#authentication-strategies)
|
|
* [add_ons](#authentication-add_ons)
|
|
|
|
|
|
|
|
|
|
|
|
### Options
|
|
| Name | Type | Default | Docs |
|
|
| --- | --- | --- | --- |
|
|
| `api`* | `module` | | The name of the Ash API to use to access this resource when doing anything authenticaiton related. |
|
|
| `subject_name` | `atom` | | The subject name is used anywhere that a short version of your resource name is needed, eg: - generating token claims, - generating routes, - form parameter nesting. This needs to be unique system-wide and if not set will be inferred from the resource name (ie `MyApp.Accounts.User` will have a subject name of `user`). |
|
|
| `get_by_subject_action_name` | `atom` | `:get_by_subject` | The name of the read action used to retrieve records. Used internally by `AshAuthentication.subject_to_user/2`. If the action doesn't exist, one will be generated for you. |
|
|
| `select_for_senders` | `list(atom)` | | A list of fields that we will ensure are selected whenever a sender will be invoked. This is useful if using something like `ash_graphql` which by default only selects what fields appear in the query, and if you are exposing these actions that way. Defaults to `[:email]` if there is an `:email` attribute on the resource, and `[]` otherwise. |
|
|
|
|
|
|
## authentication.tokens
|
|
Configure JWT settings for this resource
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Options
|
|
| Name | Type | Default | Docs |
|
|
| --- | --- | --- | --- |
|
|
| `token_resource`* | `module \| false` | | The resource used to store token information. If token generation is enabled for this resource, we need a place to store information about tokens, such as revocations and in-flight confirmations. |
|
|
| `enabled?` | `boolean` | `false` | Should JWTs be generated by this resource? |
|
|
| `store_all_tokens?` | `boolean` | `false` | Store all tokens in the `token_resource`? Some applications need to keep track of all tokens issued to any user. This is optional behaviour with `ash_authentication` in order to preserve as much performance as possible. |
|
|
| `require_token_presence_for_authentication?` | `boolean` | `false` | Require a locally-stored token for authentication? This inverts the token validation behaviour from requiring that tokens are not revoked to requiring any token presented by a client to be present in the token resource to be considered valid. Requires `store_all_tokens?` to be `true`. |
|
|
| `signing_algorithm` | `String.t` | `"HS256"` | The algorithm to use for token signing. Available signing algorithms are; EdDSA, Ed448ph, Ed448, Ed25519ph, Ed25519, PS512, PS384, PS256, ES512, ES384, ES256, RS512, RS384, RS256, HS512, HS384 and HS256. |
|
|
| `token_lifetime` | `pos_integer \| {pos_integer, :days \| :hours \| :minutes \| :seconds}` | `{14, :days}` | How long a token should be valid. Since refresh tokens are not yet supported, you should probably set this to a reasonably long time to ensure a good user experience. You can either provide a tuple with a time unit, or a positive integer, in which case the unit is assumed to be hours. Defaults to 14 days. |
|
|
| `signing_secret` | `(any, any -> any) \| module \| String.t` | | The secret used to sign tokens. Takes either a module which implements the `AshAuthentication.Secret` behaviour, a 2 arity anonymous function or a string. See the module documentation for `AshAuthentication.Secret` for more information. |
|
|
|
|
|
|
|
|
|
|
## authentication.strategies
|
|
Configure authentication strategies on this resource
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## authentication.add_ons
|
|
Additional add-ons related to, but not providing authentication
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|