diff --git a/lib/ash_authentication/dsl.ex b/lib/ash_authentication/dsl.ex index f84ae3249..989bc21c0 100644 --- a/lib/ash_authentication/dsl.ex +++ b/lib/ash_authentication/dsl.ex @@ -138,6 +138,11 @@ defmodule AshAuthentication.Dsl do "The resource used to store token information, such as in-flight confirmations, revocations, and if `store_all_tokens?` is enabled, authentication tokens themselves.", required: true ], + extra_claims: [ + type: {:or, [{:fun, 2}, :map]}, + doc: + "A function that takes the user and the options provided when generating a token (contains the tenant), and returns a map of extra claims to include in the token." + ], signing_secret: [ type: secret_type, doc: "The secret used to sign tokens. #{secret_doc}" diff --git a/lib/ash_authentication/jwt.ex b/lib/ash_authentication/jwt.ex index 40a74eb7c..53f23ac1c 100644 --- a/lib/ash_authentication/jwt.ex +++ b/lib/ash_authentication/jwt.ex @@ -110,7 +110,13 @@ defmodule AshAuthentication.Jwt do default_claims = Config.default_claims(resource, action_opts) signer = Config.token_signer(resource, opts, context) - with {:ok, token, claims} <- Joken.generate_and_sign(default_claims, extra_claims, signer), + with {:ok, more_extra_claims} <- extra_claims_for_user(purpose, user, opts), + {:ok, token, claims} <- + Joken.generate_and_sign( + default_claims, + Map.merge(extra_claims, more_extra_claims), + signer + ), :ok <- maybe_store_token(token, resource, user, purpose, action_opts) do {:ok, token, claims} else @@ -120,6 +126,22 @@ defmodule AshAuthentication.Jwt do end end + defp extra_claims_for_user(:user, user, opts) do + case AshAuthentication.Info.authentication_tokens_extra_claims(user) do + :error -> + %{} + + {:ok, nil} -> + %{} + + {:ok, extra_claims} when is_map(extra_claims) -> + extra_claims + + {:ok, extra_claims} when is_function(extra_claims) -> + extra_claims.(user, opts) + end + end + @doc """ Given a resource, generate a signed JWT with a set of claims. """ diff --git a/lib/ash_authentication/plug/helpers.ex b/lib/ash_authentication/plug/helpers.ex index 178ffd744..4c1a43869 100644 --- a/lib/ash_authentication/plug/helpers.ex +++ b/lib/ash_authentication/plug/helpers.ex @@ -223,6 +223,8 @@ defmodule AshAuthentication.Plug.Helpers do ), {:ok, subject_name} <- Info.authentication_subject_name(resource), current_subject_name <- current_subject_name(subject_name) do + user = Ash.Resource.set_metadata(user, %{claims: claims}) + conn |> Conn.assign(current_subject_name, user) |> maybe_assign_token_record(token_record, subject_name)