OpenID Connect Logo

Oidcc.Plug

Plug Integration for oidcc library.

EEF Security WG projectMain BranchModule VersionTotal DownloadLicenseLast UpdatedCoverage 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.5.0"}
]
end

You can use igniter to generate a basic setup for phoenix:

# If you haven't created your phoenix project yet
# See: https://hexdocs.pm/igniter/readme.html#creating-a-new-mix-project-using-igniter
mix igniter.new test \
--install phoenix,oidcc,oidcc_plug \
--with phx.new
# Add Igniter Phoenix Extension
mix igniter.add_extension phoenix
# Generate Provider, Controller, Router & Config
mix oidcc_plug.gen.controller \
--name MyAppWeb.AuthController \
--provider MyApp.OpenIDProvider \
--base-url /auth \
--issuer https://account.google.com \
--client-id client-id

Usage

Setup

defmodule SampleApp.Application do
# ...
@impl Application
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