fix(auth): trigger RP-initiated logout at OIDC provider
This commit is contained in:
parent
22955bdd9e
commit
ba66bc15db
4 changed files with 192 additions and 6 deletions
|
|
@ -62,6 +62,87 @@ defmodule MvWeb.AuthControllerTest do
|
|||
assert redirected_to(conn) == ~p"/"
|
||||
end
|
||||
|
||||
describe "DELETE /sign-out with OIDC configured" do
|
||||
@base_url "https://idp.example.com"
|
||||
|
||||
defp with_oidc_settings(fun) do
|
||||
{:ok, settings} = Membership.get_settings()
|
||||
|
||||
prev = %{
|
||||
oidc_client_id: settings.oidc_client_id,
|
||||
oidc_base_url: settings.oidc_base_url,
|
||||
oidc_redirect_uri: settings.oidc_redirect_uri,
|
||||
oidc_client_secret: settings.oidc_client_secret
|
||||
}
|
||||
|
||||
{:ok, _} =
|
||||
Membership.update_settings(settings, %{
|
||||
oidc_client_id: "test-client",
|
||||
oidc_base_url: @base_url,
|
||||
oidc_redirect_uri: "http://localhost:4000/auth/user/oidc/callback",
|
||||
oidc_client_secret: "test-secret"
|
||||
})
|
||||
|
||||
try do
|
||||
fun.()
|
||||
after
|
||||
Mv.Oidc.Discovery.clear_cache()
|
||||
{:ok, s} = Membership.get_settings()
|
||||
Membership.update_settings(s, prev)
|
||||
end
|
||||
end
|
||||
|
||||
test "redirects to end_session_endpoint when discovery succeeds", %{
|
||||
conn: authenticated_conn
|
||||
} do
|
||||
with_oidc_settings(fn ->
|
||||
end_session_url = "https://idp.example.com/end-session"
|
||||
|
||||
Mv.Oidc.Discovery.put_cache(
|
||||
@base_url,
|
||||
{:ok, %{"end_session_endpoint" => end_session_url}}
|
||||
)
|
||||
|
||||
conn =
|
||||
authenticated_conn
|
||||
|> conn_with_oidc_user()
|
||||
|> delete(~p"/sign-out")
|
||||
|
||||
assert redirected_to(conn, 302) == end_session_url
|
||||
end)
|
||||
end
|
||||
|
||||
test "falls back to /sign-in?oidc_failed=1 when discovery fails", %{
|
||||
conn: authenticated_conn
|
||||
} do
|
||||
with_oidc_settings(fn ->
|
||||
Mv.Oidc.Discovery.put_cache(@base_url, {:error, :test_failure})
|
||||
|
||||
conn =
|
||||
authenticated_conn
|
||||
|> conn_with_oidc_user()
|
||||
|> delete(~p"/sign-out")
|
||||
|
||||
assert redirected_to(conn) == "/sign-in?oidc_failed=1"
|
||||
end)
|
||||
end
|
||||
|
||||
test "falls back to /sign-in?oidc_failed=1 when end_session_endpoint is missing", %{
|
||||
conn: authenticated_conn
|
||||
} do
|
||||
with_oidc_settings(fn ->
|
||||
Mv.Oidc.Discovery.put_cache(@base_url, {:ok, %{"issuer" => @base_url}})
|
||||
|
||||
conn =
|
||||
authenticated_conn
|
||||
|> conn_with_oidc_user()
|
||||
|> delete(~p"/sign-out")
|
||||
|
||||
assert redirected_to(conn) == "/sign-in?oidc_failed=1"
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
defp csrf_token_from_sign_out_form(html) when is_binary(html) do
|
||||
case Regex.run(~r/name="_csrf_token"[^>]*value="([^"]+)"/, html) do
|
||||
[_, token] ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue