From 01c1fd2abd72ce122cb9f64822da9ced3562fe2a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christopher=20Cot=C3=A9?= Date: Wed, 18 Nov 2020 21:24:29 -0600 Subject: [PATCH] initial multi-auth support --- lib/router.ex | 4 ++-- lib/router/session.ex | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/router.ex b/lib/router.ex index d099f0b..0be57e6 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -10,8 +10,8 @@ defmodule Wampex.Router do topologies: [], replicas: integer(), quorum: integer(), - authentication_module: module(), - authorization_module: module() + authentication_module: module() | map(), + authorization_module: module() | map() ) :: {:ok, pid()} | {:error, {:already_started, pid()} | {:shutdown, term()} | term()} diff --git a/lib/router/session.ex b/lib/router/session.ex index 7bf57bd..5ee1e13 100644 --- a/lib/router/session.ex +++ b/lib/router/session.ex @@ -72,8 +72,8 @@ defmodule Wampex.Router.Session do realm: String.t() | nil, name: module() | nil, challenge: Challenge.t() | nil, - authentication_module: module(), - authorization_module: module(), + authentication_module: module() | map(), + authorization_module: module() | map(), roles: [module()], registrations: [], subscriptions: [], @@ -187,7 +187,7 @@ defmodule Wampex.Router.Session do } = data } = sl ) do - {actions, challenge} = maybe_challenge(auth, realm, options, session_id, tt, t) + {actions, challenge, module} = maybe_challenge(auth, realm, options, session_id, tt, t) {:ok, %SL{ @@ -196,7 +196,8 @@ defmodule Wampex.Router.Session do data | challenge: challenge, hello_received: true, - realm: realm + realm: realm, + authentication_module: module } }, [{:next_event, :internal, :transition}] ++ actions} end @@ -237,6 +238,7 @@ defmodule Wampex.Router.Session do transport: tt, transport_pid: t, subscriptions: subs, + challenge: %Challenge{auth_method: method}, realm: realm, authorization_module: am, peer: peer, @@ -246,7 +248,7 @@ defmodule Wampex.Router.Session do } = sl ) do {data, actions} = - case is_authorized?(am, peer, :subscribe, topic) do + case is_authorized?(am, peer, :subscribe, topic, method) do true -> id = RealmSession.get_id() wc = RealmSession.subscribe(db, realm, topic, {id, {self(), Node.self()}}, opts) @@ -297,6 +299,7 @@ defmodule Wampex.Router.Session do transport: tt, transport_pid: t, db: db, + challenge: %Challenge{auth_method: method}, authorization_module: am, peer: peer, id: session_id, @@ -305,7 +308,7 @@ defmodule Wampex.Router.Session do } = sl ) do {data, actions} = - case is_authorized?(am, peer, :publish, topic) do + case is_authorized?(am, peer, :publish, topic, method) do true -> pub_id = RealmSession.get_id() @@ -377,6 +380,7 @@ defmodule Wampex.Router.Session do registrations: regs, db: db, realm: realm, + challenge: %Challenge{auth_method: method}, authorization_module: am, peer: peer, register: %Register{request_id: rid, procedure: procedure} @@ -384,7 +388,7 @@ defmodule Wampex.Router.Session do } = sl ) do {data, actions} = - case is_authorized?(am, peer, :register, procedure) do + case is_authorized?(am, peer, :register, procedure, method) do true -> id = RealmSession.get_id() RealmSession.register(db, realm, procedure, {id, {self(), Node.self()}}) @@ -416,6 +420,7 @@ defmodule Wampex.Router.Session do transport_pid: t, realm: realm, request_id: ri, + challenge: %Challenge{auth_method: method}, authorization_module: am, id: session_id, peer: peer, @@ -424,7 +429,7 @@ defmodule Wampex.Router.Session do } = sl ) do {data, actions} = - case is_authorized?(am, peer, :call, proc) do + case is_authorized?(am, peer, :call, proc, method) do true -> with {callees, index} <- RealmSession.callees(db, realm, proc), {id, {pid, node}} <- get_live_callee(proxy, callees, index, 3) do @@ -720,6 +725,8 @@ defmodule Wampex.Router.Session do defp maybe_challenge(auth, realm, details, session_id, tt, t) do case details do %{"authid" => ai, "authmethods" => am} -> + auth = get_auth_module(auth, am) + case auth.authenticate?(am) do true -> ch = auth.challenge(realm, ai, session_id) @@ -735,10 +742,10 @@ defmodule Wampex.Router.Session do t ) - {[], ch} + {[], ch, auth} false -> - Logger.error("Not a supported authentication method: #{am}") + Logger.error("Not a supported authentication method: #{inspect(am)}") {[{:next_event, :internal, :abort}], nil} end @@ -748,6 +755,15 @@ defmodule Wampex.Router.Session do end end + defp get_auth_module(auth, methods) when is_map(auth) do + case Enum.find(auth, fn {k, _v} -> k in methods end) do + {_, mod} -> mod + nil -> Logger.error("Unsupported authentication methods #{inspect(methods)}: Supported #{inspect(auth)}") + end + end + + defp get_auth_module(auth, _methods), do: auth + defp get_live_callee(_proxy, [], _index, 0) do Logger.error("No live callees, tried all replicas") {:error, :no_live_callees} @@ -794,7 +810,8 @@ defmodule Wampex.Router.Session do defp maybe_update_response(data, resp), do: {data, resp} - def is_authorized?(am, peer, type, uri) do + def is_authorized?(am, peer, type, uri, method) do + am = get_auth_module(am, [method]) am.authorized?(type, uri, peer) end -- 2.45.3