Skip to content

Latest commit

 

History

History
107 lines (85 loc) · 4.41 KB

README.md

File metadata and controls

107 lines (85 loc) · 4.41 KB

APIacAuthClientJWT

An APIac.Authenticator plug that implements the client authentication part of RFC7523 (JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants).

This method consists in sending a MACed or signed JWT in the request body to the OAuth2 token endpoint, for instance:

POST /token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A
client-assertion-type%3Ajwt-bearer&
client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0.
eyJpc3Mi[...omitted for brevity...].
cC4hiUPo[...omitted for brevity...]

OpenID Connect further specifies the "client_secret_jwt" and "private_key_jwt" authentication methods (OpenID Connect Core 1.0 incorporating errata set 1 - 9. Client Authentication) refining RFC7523.

Installation

def deps do
  [
    {:apiac_auth_client_jwt, "~> 1.2"}
  ]
end

Example

plug APIacAuthClientJWT,
  client_callback: &MyApp.Client.config/1,
  protocol: :rfc7523,
  server_metadata_callback: &MyApp.metadata.get/0

Plug options

  • :iat_max_interval: the maximum time interval, in seconds, before a token with an "iat" field is considered too far in the past. Defaults to 30, which means token emitted longer than 30 seconds ago will be rejected
  • :client_callback [mandatory]: a callback that returns client configuration from its client_id. See below for more details
  • error_response_verbosity: one of :debug, :normal or :minimal. Defaults to :normal
  • :protocol: :rfc7523 or :oidc. Defaults to :oidc. When using OpenID Connect, the following additional checks are performed:
    • the "iss" JWT field must be the client id
    • the "jti" claim must be present
  • :jti_register: a module implementing the JTIRegister behaviour, to protect against token replay. Defaults to nil, mandatory if the protocol is set to :oidc
  • :server_metadata_callback [mandatory]: OAuth2 / OpenID Connect server metadata. The following fields are used:
    • "token_endpoint": the "aud" claim of the JWTs must match it
    • "token_endpoint_auth_signing_alg_values_supported": the MAC and signing algorithms supported for verifying JWTs
  • set_error_response: function called when authentication failed. Defaults to APIacAuthClientJWT.send_error_response/3

Client configuration

The client callback returns a map whose keys are those documented in OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 1.

This includes the "client_secret" field that is used for MACed JWTs.

The "token_endpoint_auth_method" is mandatory and must be set to either "client_secret_jwt" or "private_key_jwt".

Determining allowed signature verification algorithms and keys

Signature verification algorithms:

  • if the client's "token_endpoint_auth_signing_alg" is set, use this algorithm if it is allowed by the "token_endpoint_auth_signing_alg_values_supported" server metadata, otherwise, the "token_endpoint_auth_signing_alg_values_supported" value if used
  • then, the client's "token_endpoint_auth_method" is used to filter only relevant algorithms (MAC algorithms if "token_endpoint_auth_method" is set to "client_secret_jwt", signature algorithms otherwise)

Signature verification keys: if "token_endpoint_auth_method" is set to:

  • "client_secret_jwt": both the client's "client_secret" (if present) and "jwks" (if present) fields are used to create the list of suitable MAC verification keys
  • "private_key_jwt": either "jwks" or "jwks_uri" are used to retrieve suitable signature verification keys. Note that both fields should not be configured at the same time

Replay protection

Replay protection can be implemented to prevent a JWT from being reused. This is mandatory when using OpenID Connect.

The :jti_register allows configuring a module that implements the JTIRegister behaviour.

The JTIRegister.ETS implementation provides with a basic implementation for single node servers.