View Source PhxKeycloak (PhxKeycloak v0.3.0)

Settings

Main module

First of all, we have to define main module, which will be responsible for auth by Keycloak

Required params:

  • realm - realm ID

  • site - endpoint Keycloak

  • client_id - Keycloak client identity

  • client_secret - Keycloak client secret token

  • redirect_uri - callback for your app

Optional params:

  • expected_group - Role (Group), which have access to application
  defmodule MyAppWeb.Keycloak do
    use PhxKeycloak, realm: "cronos",
      site: "http://localhost:8080",
      client_id: "cronos_check_app",
      client_secret: "7c9fb08e-2d11-4921-bc02-cc21c92b6139",
      redirect_uri: "http://localhost:4000/callback",
      expected_group: "app_admin"
  end

Plugs

After this we have next Plug's:

  • MyAppWeb.Keycloak.Plugs.RefreshUserTokenPlug - token update and refresh

  • MyAppWeb.Keycloak.Plugs.GetClaimsPlug - get claims about user

  • MyAppWeb.Keycloak.Plugs.RedirectUnauthorizedUserToLoginPlug, redirect_route: "/login" - redirect to login page

Controller

Define controller, for login and logout user:

defmodule MyAppWeb.AuthorizeController do
  use MyAppWeb, :controller
  alias MyAppWeb.Keycloak

  def login(conn, _) do
    redirect(conn, external: Keycloak.authorize_url())
  end

  def logout(conn, _) do
    refresh_token = get_session(conn, :refresh_token)

    Keycloak.logout(refresh_token)

    conn
    |> clear_session()
    |> redirect(to: "/")
  end

  def callback(conn, %{"code" => code}) do
    {_access_token, refresh_token} = Keycloak.get_tokens_by_code(code)

    conn
    |> put_session(:refresh_token, refresh_token)
    |> redirect(to: "/")
  end
end

Router

In MyAppWeb.Router add next pipeline's:

...
pipeline :keycloak do
  plug Keycloak.Plugs.RefreshUserTokenPlug
  plug Keycloak.Plugs.GetClaimsPlug
end

pipeline :auth_or_redirect do
  plug Keycloak.Plugs.RedirectUnauthorizedUserToLoginPlug, redirect_route: "/login"
end
...

Now, our router looks like this:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router

  alias MyAppWeb.Keycloak

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :keycloak do
    plug Keycloak.Plugs.RefreshUserTokenPlug, Keycloak
    plug Keycloak.Plugs.GetClaimsPlug, Keycloak
  end

  pipeline :auth_or_redirect do
    plug Keycloak.Plugs.RedirectUnauthorizedUserToLoginPlug, redirect_route: "/login"
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", MyAppWeb do
    pipe_through :browser
    pipe_through :keycloak
    pipe_through :auth_or_redirect

    # ...my_web_app_routes
  end

  scope "/", MyAppWeb do
    pipe_through :browser
    pipe_through :keycloak

    get "/login", AuthorizeController, :login
    post "/logout", AuthorizeController, :logout
    get "/callback", AuthorizeController, :callback
  end
end