Ueberauth.Strategy.Authify (Ueberauth Authify v0.1.0)

View Source

Provides an Ueberauth strategy for authenticating with Authify, a self-hosted, multi-tenant identity provider implementing OpenID Connect on top of OAuth 2.0.

Since Authify is multi-tenant, both the server base URL and the organization slug are required; all endpoints (authorize, token, userinfo and JWKS) are scoped to the organization. Configure the site and OAuth credentials under the Ueberauth.Strategy.Authify.OAuth namespace:

config :ueberauth, Ueberauth.Strategy.Authify.OAuth,
  site: "https://authify.example.com",
  client_id: "YOUR_CLIENT_ID",
  client_secret: "YOUR_CLIENT_SECRET"

and register the provider with its organization:

config :ueberauth, Ueberauth,
  providers: [
    authify: {Ueberauth.Strategy.Authify, [organization: "my-org"]}
  ]

Options

  • :organization (required) - the Authify organization slug
  • :default_scope - scopes requested from Authify; defaults to "openid profile email". "openid" is required for an ID token
  • :uid_field - the ID token claim used as the uid; defaults to :sub
  • :verify_id_token - verify the ID token signature and claims (recommended, default); set to false to rely solely on the userinfo endpoint
  • :leeway - seconds of slack allowed when validating time-based ID token claims; defaults to 60
  • :pkce - use PKCE (S256) for the authorization code exchange; enabled by default

The request phase also forwards an optional prompt request parameter (Authify honors prompt=consent) and an optional max_age parameter to require a recent authentication, validated against the ID token's auth_time claim.

Flow

  1. The request phase redirects to the organization's authorize endpoint with a per-login nonce and a PKCE code_challenge, both stored in the session for the callback.
  2. The callback phase exchanges the authorization code (with the PKCE verifier) for tokens, verifies the RS256 ID token against the organization's JWKS (refetching on key rotation) and validates the iss, sub, aud, exp, iat, nonce and (when max_age was requested) auth_time claims.
  3. The auth hash is built from the verified ID token claims; the raw claims and the full %OAuth2.AccessToken{} are available in extra.raw_info.

The strategy requires the session (via Plug.Session) to carry the nonce and PKCE verifier between the two phases; Phoenix applications already provide this.

Misconfiguration (a missing :site or :organization) fails the request phase with a missing_configuration error rather than redirecting the user to Authify with a broken URL.

Summary

Functions

Includes the credentials from the Authify token response.

Populates the extra section of the Ueberauth.Auth struct with the verified ID token claims and the full token.

Handles the callback from Authify, exchanging the code for tokens and verifying the ID token while building the auth struct components.

Cleans up the private area of the connection used during the callback.

Handles the redirect to the organization's Authify authorize endpoint.

Fetches the fields to populate the info section of the Ueberauth.Auth struct, from the standard OIDC claims.

The uid for the user, from the :uid_field claim (default sub).

Functions

credentials(conn)

Includes the credentials from the Authify token response.

default_options()

Callback implementation for Ueberauth.Strategy.default_options/0.

extra(conn)

Populates the extra section of the Ueberauth.Auth struct with the verified ID token claims and the full token.

handle_callback!(conn)

Handles the callback from Authify, exchanging the code for tokens and verifying the ID token while building the auth struct components.

handle_cleanup!(conn)

Cleans up the private area of the connection used during the callback.

handle_request!(conn)

Handles the redirect to the organization's Authify authorize endpoint.

info(conn)

Fetches the fields to populate the info section of the Ueberauth.Auth struct, from the standard OIDC claims.

Note that location is mapped from zoneinfo (an IANA timezone) and that locale deliberately does not end up there, mirroring the behavior of the Ruby omniauth-authify gem.

uid(conn)

The uid for the user, from the :uid_field claim (default sub).