View Source Oidcc.Token (Oidcc v3.0.1)

Facilitate OpenID Code/Token Exchanges

Telemetry

  • [:oidcc, :request_token, :start]

    • Description: Emitted at the start of requesting a code token
    • Measurements: %{system_time: non_neg_integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :request_token, :stop]

    • Description: Emitted at the end of requesting a code token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :request_token, :exception]

    • Description: Emitted at the end of requesting a code token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :refresh_token, :start]

    • Description: Emitted at the start of refreshing a token
    • Measurements: %{system_time: non_neg_integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :refresh_token, :stop]

    • Description: Emitted at the end of refreshing a token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :refresh_token, :exception]

    • Description: Emitted at the end of refreshing a token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :jwt_profile_token, :start]

    • Description: Emitted at the start of exchanging a JWT profile token
    • Measurements: %{system_time: non_neg_integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :jwt_profile_token, :stop]

    • Description: Emitted at the end of exchanging a JWT profile token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :jwt_profile_token, :exception]

    • Description: Emitted at the end of exchanging a JWT profile token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :client_credentials, :start]

    • Description: Emitted at the start of requesting a client credentials token
    • Measurements: %{system_time: non_neg_integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :client_credentials, :stop]

    • Description: Emitted at the end of requesting a client credentials token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}
  • [:oidcc, :client_credentials, :exception]

    • Description: Emitted at the end of requesting a client credentials token
    • Measurements: %{duration: integer(), monotonic_time: integer()}
    • Metadata: %{issuer: :uri_string.uri_string(), client_id: String.t()}

Summary

Functions

Retrieve Client Credential Token

Retrieve JSON Web Token (JWT) Profile Token

retrieve the token using the authcode received before and directly validate the result.

Types

@type t() :: %Oidcc.Token{
  access: Oidcc.Token.Access.t() | none(),
  id: Oidcc.Token.Id.t() | none(),
  refresh: Oidcc.Token.Refresh.t() | none(),
  scope: :oidcc_scope.scopes()
}

Functions

Link to this function

client_credentials(client_context, opts)

View Source (since 3.0.0)
@spec client_credentials(
  client_context :: Oidcc.ClientContext.t(),
  opts :: :oidcc_token.client_credentials_opts()
) :: {:ok, t()} | {:error, :oidcc_token.error()}

Retrieve Client Credential Token

See https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4

For a high level interface using Oidcc.ProviderConfiguration.Worker see Oidcc.client_credentials_token/4.

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://erlef-test-w4a8z2.zitadel.cloud"
...>   })
...>
...> {:ok, client_context} =
...>   Oidcc.ClientContext.from_configuration_worker(
...>     pid,
...>     System.fetch_env!("CLIENT_CREDENTIALS_CLIENT_ID"),
...>     System.fetch_env!("CLIENT_CREDENTIALS_CLIENT_SECRET")
...>   )
...>
...> {:ok, %Oidcc.Token{}} =
...>   Oidcc.Token.client_credentials(
...>     client_context,
...>     %{scope: ["scope"]}
...>   )
Link to this function

jwt_profile(subject, client_context, jwk, opts)

View Source (since 3.0.0)
@spec jwt_profile(
  subject :: String.t(),
  client_context :: Oidcc.ClientContext.t(),
  jwk :: JOSE.JWK.t(),
  opts :: :oidcc_token.jwt_profile_opts()
) :: {:ok, t()} | {:error, :oidcc_token.error()}

Retrieve JSON Web Token (JWT) Profile Token

See https://datatracker.ietf.org/doc/html/rfc7523#section-4

For a high level interface using Oidcc.ProviderConfiguration.Worker see Oidcc.jwt_profile_token/6.

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://erlef-test-w4a8z2.zitadel.cloud"
...>   })
...>
...> {:ok, client_context} =
...>   Oidcc.ClientContext.from_configuration_worker(
...>     pid,
...>     "client_id",
...>     "client_secret"
...>   )
...>
...> %{"key" => key, "keyId" => kid, "userId" => subject} = "JWT_PROFILE"
...>   |> System.fetch_env!()
...>   |> JOSE.decode()
...>
...> jwk = JOSE.JWK.from_pem(key)
...>
...> {:ok, %Oidcc.Token{}} =
...>   Oidcc.Token.jwt_profile(
...>     subject,
...>     client_context,
...>     jwk,
...>     %{scope: ["urn:zitadel:iam:org:project:id:zitadel:aud"], kid: kid}
...>   )
Link to this function

refresh(token, client_context, opts)

View Source (since 3.0.0)
@spec refresh(
  refresh_token :: String.t(),
  client_context :: Oidcc.ClientContext.t(),
  opts :: :oidcc_token.refresh_opts()
) :: {:ok, t()} | {:error, :oidcc_token.error()}
@spec refresh(
  token :: t(),
  client_context :: Oidcc.ClientContext.t(),
  opts :: :oidcc_token.refresh_opts_no_sub()
) :: {:ok, t()} | {:error, :oidcc_token.error()}

Refresh Token

For a high level interface using Oidcc.ProviderConfiguration.Worker see Oidcc.refresh_token/5.

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://api.login.yahoo.com"
...>   })
...>
...> {:ok, client_context} =
...>   Oidcc.ClientContext.from_configuration_worker(
...>     pid,
...>     "client_id",
...>     "client_secret"
...>   )
...>
...> # Get refresh_token fromm redirect
...> refresh_token = "refresh_token"
...>
...> Oidcc.Token.refresh(
...>   refresh_token,
...>   client_context,
...>   %{expected_subject: "sub"}
...> )
...> # => {:ok, %Oidcc.Token{}}
Link to this function

retrieve(auth_code, client_context, opts)

View Source (since 3.0.0)
@spec retrieve(
  auth_code :: String.t(),
  client_context :: Oidcc.ClientContext.t(),
  opts :: :oidcc_token.retrieve_opts()
) :: {:ok, t()} | {:error, :oidcc_token.error()}

retrieve the token using the authcode received before and directly validate the result.

the authcode was sent to the local endpoint by the OpenId Connect provider, using redirects

For a high level interface using Oidcc.ProviderConfiguration.Worker see Oidcc.retrieve_token/5.

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://api.login.yahoo.com"
...>   })
...>
...> {:ok, client_context} =
...>   Oidcc.ClientContext.from_configuration_worker(
...>     pid,
...>     "client_id",
...>     "client_secret"
...>   )
...>
...> # Get auth_code fromm redirect
...> auth_code = "auth_code"
...>
...> Oidcc.Token.retrieve(
...>   auth_code,
...>   client_context,
...>   %{redirect_uri: "https://my.server/return"}
...> )
...> # => {:ok, %Oidcc.Token{}}
Link to this function

validate_id_token(id_token, client_context, nonce)

View Source (since 3.0.0)
@spec validate_id_token(
  id_token :: String.t(),
  client_context :: Oidcc.ClientContext.t(),
  nonce :: String.t() | any()
) :: {:ok, :oidcc_jwt_util.claims()} | {:error, :oidcc_token.error()}

Validate ID Token

Usually the id token is validated using retrieve/3. If you get the token passed from somewhere else, this function can validate it.

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://api.login.yahoo.com"
...>   })
...>
...> {:ok, client_context} =
...>   Oidcc.ClientContext.from_configuration_worker(
...>     pid,
...>     "client_id",
...>     "client_secret"
...>   )
...>
...> #Get IdToken from somewhere
...> id_token = "id_token"
...>
...> Oidcc.Token.validate_id_token(id_token, client_context, :any)
...> # => {:ok, %{"sub" => "sub", ... }}