oidcc_provider_configuration (Oidcc v3.9.0)

Copy Markdown View Source

Tooling to load and parse Openid Configuration.

Records

To use the record, import the definition:

-include_lib(["oidcc/include/oidcc_provider_configuration.hrl"]).

Telemetry

See Oidcc.ProviderConfiguration.

Summary

Types

Decoded JSON document as served by the provider.

Decoded JWKS document as served by the provider.

Configure configuration loading / parsing.

Allow Specification Non-compliance.

t()

Record containing OpenID and OAuth 2.0 Configuration.

Functions

Load OpenID Configuration into a oidcc_provider_configuration:t/0 record.

Load OpenID Configuration, keeping the document the provider served.

Load JWKs into a jose_jwk:key/0 record.

Load JWKs, keeping the document the provider served.

Types

document()

(since 3.9.0)
-type document() :: #{binary() => term()}.

Decoded JSON document as served by the provider.

This is the document the endpoint returned, before oidcc merges document_overrides into it or coerces it into a record. Unlike a decoded record it can be re-encoded losslessly, which is what makes it suitable for persisting the provider's metadata.

error()

(since 3.0.0)
-type error() ::
          invalid_content_type |
          {issuer_mismatch, Issuer :: binary()} |
          {invalid_issuer, Issuer :: binary()} |
          {invalid_document, Document :: term()} |
          oidcc_decode_util:error() |
          oidcc_http_util:error().

jwks_document()

(since 3.9.0)
-type jwks_document() :: document() | [term()].

Decoded JWKS document as served by the provider.

RFC 7517 section 5 defines a JWK Set as a JSON object with a keys member, but jose_jwk:from/1 also accepts a bare array of keys and some providers serve one, so both shapes reach the caller.

opts()

(since 3.0.0)
-type opts() ::
          #{fallback_expiry => timeout(),
            request_opts => oidcc_http_util:request_opts(),
            quirks => quirks()}.

Configure configuration loading / parsing.

Parameters

  • fallback_expiry - How long to keep configuration cached if the server doesn't specify expiry.
  • request_opts - config for HTTP request.

quirks()

(since 3.1.0)
-type quirks() ::
          #{allow_unsafe_http => boolean(), document_overrides => map(), issuer_regex => binary()}.

Allow Specification Non-compliance.

Exceptions

  • allow_unsafe_http - Allow unsafe HTTP. Use this for development providers and never in production.
  • document_overrides - a map to merge with the real OIDD document, in case the OP left out some values.
  • issuer_regex - Optional regex pattern to match against the issuer claim instead of requiring an exact match. This may be necessary for certain providers that do not conform to the OpenID specification, such as Microsoft Entra ID where the issuer is 'https://login.microsoftonline.com/{tenantid}/v2.0' in the OpenID configuration.

t()

(since 3.0.0)
-type t() ::
          #oidcc_provider_configuration{issuer :: uri_string:uri_string(),
                                        issuer_regex :: binary() | undefined,
                                        authorization_endpoint :: uri_string:uri_string(),
                                        token_endpoint :: uri_string:uri_string() | undefined,
                                        userinfo_endpoint :: uri_string:uri_string() | undefined,
                                        jwks_uri :: uri_string:uri_string() | undefined,
                                        registration_endpoint :: uri_string:uri_string() | undefined,
                                        scopes_supported :: [binary()] | undefined,
                                        response_types_supported :: [binary()],
                                        response_modes_supported :: [binary()],
                                        grant_types_supported :: [binary()],
                                        acr_values_supported :: [binary()] | undefined,
                                        subject_types_supported :: [pairwise | public],
                                        id_token_signing_alg_values_supported :: [binary()],
                                        id_token_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        id_token_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        userinfo_signing_alg_values_supported :: [binary()] | undefined,
                                        userinfo_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        userinfo_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        request_object_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        request_object_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        request_object_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        token_endpoint_auth_methods_supported :: [binary()],
                                        token_endpoint_auth_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        display_values_supported :: [binary()] | undefined,
                                        claim_types_supported :: [normal | aggregated | distributed],
                                        claims_supported :: [binary()] | undefined,
                                        service_documentation :: uri_string:uri_string() | undefined,
                                        claims_locales_supported :: [binary()] | undefined,
                                        ui_locales_supported :: [binary()] | undefined,
                                        claims_parameter_supported :: boolean(),
                                        request_parameter_supported :: boolean(),
                                        request_uri_parameter_supported :: boolean(),
                                        require_request_uri_registration :: boolean(),
                                        op_policy_uri :: uri_string:uri_string() | undefined,
                                        op_tos_uri :: uri_string:uri_string() | undefined,
                                        revocation_endpoint :: uri_string:uri_string() | undefined,
                                        revocation_endpoint_auth_methods_supported :: [binary()],
                                        revocation_endpoint_auth_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        introspection_endpoint :: uri_string:uri_string() | undefined,
                                        introspection_endpoint_auth_methods_supported :: [binary()],
                                        introspection_endpoint_auth_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        code_challenge_methods_supported :: [binary()] | undefined,
                                        end_session_endpoint :: uri_string:uri_string() | undefined,
                                        require_pushed_authorization_requests :: boolean(),
                                        pushed_authorization_request_endpoint ::
                                            uri_string:uri_string() | undefined,
                                        authorization_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        authorization_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        authorization_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        authorization_response_iss_parameter_supported :: boolean(),
                                        dpop_signing_alg_values_supported :: [binary()] | undefined,
                                        require_signed_request_object :: boolean(),
                                        mtls_endpoint_aliases :: #{binary() => uri_string:uri_string()},
                                        extra_fields :: #{binary() => term()},
                                        tls_client_certificate_bound_access_tokens :: boolean()}.

Record containing OpenID and OAuth 2.0 Configuration.

See:

All unrecognized fields are stored in extra_fields.

Functions

decode_configuration(Configuration)

(since 3.0.0)
-spec decode_configuration(Configuration) -> {ok, t()} | {error, error()} when Configuration :: map().

See decode_configuration/2.

decode_configuration(Configuration, Opts)

(since 3.1.0)
-spec decode_configuration(Configuration, Opts) -> {ok, t()} | {error, error()}
                              when Configuration :: map(), Opts :: opts().

Decode JSON into a oidcc_provider_configuration:t/0 record.

Examples

{ok, {{"HTTP/1.1",200,"OK"}, _Headers, Body}} =
  httpc:request("https://accounts.google.com/.well-known/openid-configuration"),

{ok, DecodedJson} = your_json_lib:decode(Body),

{ok, #oidcc_provider_configuration{}} =
  oidcc_provider_configuration:decode_configuration(DecodedJson).

load_configuration(Issuer)

(since 3.1.0)
-spec load_configuration(Issuer) ->
                            {ok, {Configuration :: t(), Expiry :: pos_integer()}} | {error, error()}
                            when Issuer :: uri_string:uri_string().

See load_configuration/2.

load_configuration(Issuer, Opts)

(since 3.0.0)
-spec load_configuration(Issuer, Opts) ->
                            {ok, {Configuration :: t(), Expiry :: pos_integer()}} | {error, error()}
                            when Issuer :: uri_string:uri_string(), Opts :: opts().

Load OpenID Configuration into a oidcc_provider_configuration:t/0 record.

Examples

{ok, #oidcc_provider_configuration{}} =
  oidcc_provider_configuration:load_configuration("https://accounts.google.com").

load_configuration_raw(Issuer, Opts)

(since 3.9.0)
-spec load_configuration_raw(Issuer, Opts) ->
                                {ok,
                                 {Configuration :: t(), Expiry :: pos_integer(), Document :: document()}} |
                                {error, error()}
                                when Issuer :: uri_string:uri_string(), Opts :: opts().

Load OpenID Configuration, keeping the document the provider served.

Same as load_configuration/2, but additionally returns the decoded JSON document. The record cannot be re-encoded losslessly - extra_fields holds only the keys the decoder did not recognize, every other key is coerced into a typed record field, and issuer_regex is not an OpenID Discovery field at all - so callers that persist provider metadata need the document itself.

Examples

{ok, {#oidcc_provider_configuration{}, _Expiry, #{<<"issuer">> := Issuer}}} =
  oidcc_provider_configuration:load_configuration_raw(
    "https://accounts.google.com",
    #{}
  ).

load_jwks(JwksUri, Opts)

(since 3.0.0)
-spec load_jwks(JwksUri, Opts) ->
                   {ok, {Jwks :: jose_jwk:key(), Expiry :: pos_integer()}} | {error, term()}
                   when JwksUri :: uri_string:uri_string(), Opts :: opts().

Load JWKs into a jose_jwk:key/0 record.

Examples

{ok, #jose_jwk{}} =
  oidcc_provider_configuration:load_jwks("https://www.googleapis.com/oauth2/v3/certs").

load_jwks_raw(JwksUri, Opts)

(since 3.9.0)
-spec load_jwks_raw(JwksUri, Opts) ->
                       {ok,
                        {Jwks :: jose_jwk:key(), Expiry :: pos_integer(), Document :: jwks_document()}} |
                       {error, error()}
                       when JwksUri :: uri_string:uri_string(), Opts :: opts().

Load JWKs, keeping the document the provider served.

Same as load_jwks/2, but additionally returns the decoded JSON document, for callers that persist the key set rather than only using it.

Examples

{ok, {#jose_jwk{}, _Expiry, #{<<"keys">> := _Keys}}} =
  oidcc_provider_configuration:load_jwks_raw(
    "https://www.googleapis.com/oauth2/v3/certs",
    #{}
  ).