Skip to content

erlef/oidcc_plug

OpenID Connect Logo

Oidcc.Plug

Plug Integration for oidcc library.

EEF Security WG project Main Branch Module Version Total Download License Last Updated Coverage Status


OpenID Connect Certified Logo

OpenID Certified by Jonatan Männchen at the Erlang Ecosystem Foundation of multiple Relaying Party conformance profiles of the OpenID Connect protocol: For details, check the Conformance Test Suite.


Erlang Ecosystem Foundation Logo

The development of the library and the certification is funded as an Erlang Ecosystem Foundation stipend entered by the Security Working Group.


Installation

The package can be installed by adding oidcc_plug to your list of dependencies in mix.exs:

def deps do
  [
    {:oidcc_plug, "~> 0.1.0"}
  ]
end

Usage

Setup

defmodule SampleApp.Application do
  # ...

  @impl true
  def start(_type, _args) do
    children = [
      # ...

      {Oidcc.ProviderConfiguration.Worker, %{
        issuer: "https://accounts.google.com",
        name: SampleApp.GoogleOpenIdConfigurationProvider
      }},

      # Start the Endpoint (http/https)
      SampleAppWeb.Endpoint
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: SampleApp.Supervisor]
    Supervisor.start_link(children, opts)
  end

  # ...
end

Authorization Flow

defmodule SampleAppWeb.OidccController do
  use SampleAppWeb, :controller

  plug Oidcc.Plug.Authorize,
    [
      provider: TestWorks.OpenIdConfigurationProvider,
      client_id: "client_id",
      client_secret: "client_secret",
      redirect_uri: &__MODULE__.callback_uri/0
    ]
    when action in [:authorize]

  plug Oidcc.Plug.AuthorizationCallback,
    [
      provider: TestWorks.OpenIdConfigurationProvider,
      client_id: "client_id",
      client_secret: "client_secret",
      redirect_uri: &__MODULE__.callback_uri/0
    ]
    when action in [:callback]

  @doc false
  def callback_uri, do: url(~p"/oidcc/callback")

  def authorize(conn, _params), do: conn

  def callback(%Plug.Conn{private: %{
    Oidcc.Plug.AuthorizationCallback => {:ok, {_token, userinfo}}}
  } = conn, params) do
    conn
    |> put_session("oidcc_claims", userinfo)
    |> redirect(to: "/")
  end

  def callback(%Plug.Conn{private: %{
    Oidcc.Plug.AuthorizationCallback => {:error, reason}
  }} = conn, _params) do
    conn
    |> put_status(400)
    |> render(:error, reason: reason)
  end
end

API (Check access token header)

defmodule SampleAppWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :sample_app

  # ...

  plug Oidcc.Plug.ExtractAuthorization

  @client_id Application.compile_env!(:sample_app, [:openid_credentials, :client_id])
  @client_secret Application.compile_env!(:sample_app, [:openid_credentials, :client_secret])

  # Ensure Authorization Token provided
  plug Oidcc.Plug.RequireAuthorization

  # Check Token via Introspection
  plug Oidcc.Plug.IntrospectToken,
    provider: SampleApp.GoogleOpenIdConfigurationProvider,
    client_id: @client_id,
    client_secret: @client_secret

  # OR: Check Token via Userinfo
  plug Oidcc.Plug.LoadUserinfo,
    provider: SampleApp.GoogleOpenIdConfigurationProvider,
    client_id: @client_id,
    client_secret: @client_secret

  # OR: Check Token via JWT validation
  plug Oidcc.Plug.ValidateJwtToken,
    provider: SampleApp.GoogleOpenIdConfigurationProvider,
    client_id: @client_id,
    client_secret: @client_secret

  plug SampleAppWeb.Router
end