View Source Oidcc (Oidcc v3.2.0)

OpenID Connect High Level Interface

Setup

{:ok, _pid} =
  Oidcc.ProviderConfiguration.Worker.start_link(%{
  issuer: "https://accounts.google.com",
  name: MyApp.GoogleConfigProvider
})

or via a supervisor

Supervisor.init([
  {Oidcc.ProviderConfiguration.Worker, %{issuer: "https://accounts.google.com"}}
], strategy: :one_for_one)

Global Configuration

  • max_clock_skew (default 0) - Maximum allowed clock skew for JWT exp / nbf validation

Summary

Functions

Link to this function

client_credentials_token(provider_configuration_name, client_id, client_secret, opts)

View Source (since 3.0.0)
@spec client_credentials_token(
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_token.client_credentials_opts() | :oidcc_client_context.opts()
) ::
  {:ok, Oidcc.Token.t()}
  | {:error, :oidcc_client_context.error() | :oidcc_token.error()}

Retrieve Client Credential Token

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

Examples

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

create_redirect_url(provider_configuration_name, client_id, client_secret, opts)

View Source (since 3.0.0)
@spec create_redirect_url(
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_authorization.opts() | :oidcc_client_context.opts()
) ::
  {:ok, :uri_string.uri_string()}
  | {:error, :oidcc_client_context.error() | :oidcc_client_context.error()}

Create Auth Redirect URL

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>   issuer: "https://accounts.google.com"
...> })
...>
...> {:ok, _redirect_uri} =
...>   Oidcc.create_redirect_url(
...>     pid,
...>     "client_id",
...>     "client_secret",
...>     %{redirect_uri: "https://my.server/return"}
...>   )
Link to this function

initiate_logout_url(token, provider_configuration_name, client_id, opts \\ %{})

View Source (since 3.0.0)
@spec initiate_logout_url(
  token :: id_token | Oidcc.Token.t() | :undefined,
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  opts :: :oidcc_logout.initiate_url_opts() | :oidcc_client_context.opts()
) ::
  {:ok, :uri_string.uri_string()}
  | {:error, :oidcc_client_context.error() | :oidcc_logout.error()}
when id_token: String.t()

Create Initiate URI for Relaying Party initiated Logout

See [https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout]

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://erlef-test-w4a8z2.zitadel.cloud"
...>   })
...>
...> # Get access_token from Oidcc.Token.retrieve/3
...> token = "token"
...>
...> {:ok, _redirect_uri} = Oidcc.initiate_logout_url(
...>   token,
...>   pid,
...>   "client_id"
...> )
Link to this function

introspect_token(token, provider_configuration_name, client_id, client_secret, opts \\ %{})

View Source (since 3.0.0)
@spec introspect_token(
  access_token :: String.t() | Oidcc.Token.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_token_introspection.opts() | :oidcc_client_context.opts()
) ::
  {:ok, Oidcc.TokenIntrospection.t()}
  | {:error, :oidcc_client_context.error() | :oidcc_token_introspection.error()}

Introspect the given access token

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://api.login.yahoo.com"
...>   })
...>
...> Oidcc.introspect_token(
...>   "access_token",
...>   pid,
...>   "client_id",
...>   "client_secret"
...> )
...> # => {:ok, %Oidcc.TokenIntrospection{}}
Link to this function

jwt_profile_token(subject, provider_configuration_name, client_id, client_secret, jwk, opts)

View Source (since 3.0.0)
@spec jwt_profile_token(
  subject :: String.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  jwk :: JOSE.JWK.t(),
  opts :: :oidcc_token.jwt_profile_opts() | :oidcc_client_context.opts()
) ::
  {:ok, Oidcc.Token.t()}
  | {:error, :oidcc_client_context.error() | :oidcc_token.error()}

Retrieve JSON Web Token (JWT) Profile Token

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

Examples

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

refresh_token(token, provider_configuration_name, client_id, client_secret, opts \\ %{})

View Source (since 3.0.0)
@spec refresh_token(
  refresh_token :: String.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_token.refresh_opts() | :oidcc_client_context.opts()
) :: {:ok, Oidcc.Token.t()} | {:error, :oidcc_token.error()}
@spec refresh_token(
  token :: Oidcc.Token.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_token.refresh_opts_no_sub() | :oidcc_client_context.opts()
) ::
  {:ok, Oidcc.Token.t()}
  | {:error, :oidcc_client_context.error() | :oidcc_token.error()}

Refresh Token

Examples

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

retrieve_token(auth_code, provider_configuration_name, client_id, client_secret, opts)

View Source (since 3.0.0)
@spec retrieve_token(
  auth_code :: String.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_token.retrieve_opts() | :oidcc_client_context.opts()
) ::
  {:ok, Oidcc.Token.t()}
  | {:error, :oidcc_client_context.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

Examples

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

retrieve_userinfo(token, provider_configuration_name, client_id, client_secret, opts \\ %{})

View Source (since 3.0.0)
@spec retrieve_userinfo(
  token :: Oidcc.Token.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_userinfo.retrieve_opts_no_sub() | :oidcc_client_context.opts()
) :: {:ok, :oidcc_jwt_util.claims()} | {:error, :oidcc_userinfo.error()}
@spec retrieve_userinfo(
  access_token :: String.t(),
  provider_configuration_name :: GenServer.name(),
  client_id :: String.t(),
  client_secret :: String.t(),
  opts :: :oidcc_userinfo.retrieve_opts() | :oidcc_client_context.opts()
) ::
  {:ok, :oidcc_jwt_util.claims()}
  | {:error, :oidcc_client_context.error() | :oidcc_userinfo.error()}

Load userinfo for the given token

Examples

iex> {:ok, pid} =
...>   Oidcc.ProviderConfiguration.Worker.start_link(%{
...>     issuer: "https://api.login.yahoo.com"
...>   })
...>
...> # Get access_token from Oidcc.Token.retrieve/3
...> access_token = "access_token"
...>
...> Oidcc.retrieve_userinfo(
...>   access_token,
...>   pid,
...>   "client_id",
...>   "client_secret",
...>   %{expected_subject: "sub"}
...> )
...> # => {:ok, %{"sub" => "sub"}}