Oidcc (Oidcc v3.5.0)
View SourceOpenID 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
(default0
) - Maximum allowed clock skew for JWTexp
/nbf
validation, in seconds
Summary
Functions
Retrieve Client Credential Token
Create Auth Redirect URL
Create Initiate URI for Relaying Party initiated Logout
Introspect the given access token
Retrieve JSON Web Token (JWT) Profile Token
Refresh Token
retrieve the token using the authcode received before and directly validate the result.
Load userinfo for the given token
Functions
@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: ["openid"]}
...> )
@spec create_redirect_url( provider_configuration_name :: GenServer.name(), client_id :: String.t(), client_secret :: String.t() | :unauthenticated, opts :: :oidcc_authorization.opts() | :oidcc_client_context.opts() ) :: {:ok, :uri_string.uri_string()} | {: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"}
...> )
@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"
...> )
@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{}}
@spec jwt_profile_token( subject :: String.t(), provider_configuration_name :: GenServer.name(), client_id :: String.t(), client_secret :: String.t() | :unauthenticated, 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,
...> "JWT Profile Test",
...> "client_secret",
...> jwk,
...> %{scope: ["openid", "urn:zitadel:iam:org:project:id:zitadel:aud"], kid: kid}
...> )
@spec refresh_token( refresh_token :: String.t(), provider_configuration_name :: GenServer.name(), client_id :: String.t(), client_secret :: String.t() | :unauthenticated, 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() | :unauthenticated, 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{}}
@spec retrieve_token( auth_code :: String.t(), provider_configuration_name :: GenServer.name(), client_id :: String.t(), client_secret :: String.t() | :unauthenticated, 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{}}
@spec retrieve_userinfo( token :: Oidcc.Token.t(), provider_configuration_name :: GenServer.name(), client_id :: String.t(), client_secret :: String.t() | :unauthenticated, 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"}}