Improve validation for token exchange endpoint
This commit is contained in:
parent
fbb33369a8
commit
8129d916e3
2 changed files with 34 additions and 19 deletions
|
@ -4,7 +4,6 @@ defmodule ComfycampWeb.OauthController do
|
|||
alias Comfycamp.Accounts
|
||||
alias Comfycamp.SSO
|
||||
alias Comfycamp.SSO.OIDCApp
|
||||
alias Comfycamp.SSO.OIDCCode
|
||||
alias Comfycamp.SSO.IDToken
|
||||
alias Comfycamp.Token
|
||||
|
||||
|
@ -78,31 +77,41 @@ defmodule ComfycampWeb.OauthController do
|
|||
end
|
||||
|
||||
def token(conn, params = %{"code" => code_value, "redirect_uri" => redirect_uri}) do
|
||||
{:ok, client_id, client_secret} = get_client_info(conn, params)
|
||||
with {:client_info, {:ok, client_id, client_secret}} <-
|
||||
{:client_info, get_client_info(conn, params)},
|
||||
{:code, code} <- {:code, SSO.get_oidc_code!(code_value)},
|
||||
{:uri, ^redirect_uri} <- {:uri, code.redirect_uri},
|
||||
{:app, oidc_app = %OIDCApp{enabled: true, client_id: ^client_id}} <-
|
||||
{:app, SSO.get_oidc_app_by_secret!(client_secret)},
|
||||
{:code_ref, ^client_id} <- {:code_ref, code.oidc_app.client_id} do
|
||||
SSO.delete_oidc_code(code)
|
||||
|
||||
# Check that code is still valid and redirect uri has not been altered.
|
||||
%OIDCCode{redirect_uri: ^redirect_uri} = code = SSO.get_oidc_code!(code_value)
|
||||
{access_token, refresh_token} = Accounts.generate_oauth_tokens(code.user)
|
||||
|
||||
# Check that client provided a valid secret for an active OIDC app.
|
||||
%OIDCApp{enabled: true, client_id: ^client_id} =
|
||||
oidc_app = SSO.get_oidc_app_by_secret!(client_secret)
|
||||
id_token = IDToken.build_id_token(code.user, oidc_app.client_id)
|
||||
{:ok, signed_id_token} = Token.sign(id_token, client_secret)
|
||||
|
||||
# Check that OIDC app is referenced by provided code.
|
||||
^client_id = code.oidc_app.client_id
|
||||
render(conn, :token,
|
||||
access_token: Base.url_encode64(access_token),
|
||||
refresh_token: Base.url_encode64(refresh_token),
|
||||
id_token: signed_id_token
|
||||
)
|
||||
else
|
||||
{:client_info, _} ->
|
||||
render(conn, :error, description: "Нет client id или client secret")
|
||||
|
||||
# Delete the code.
|
||||
SSO.delete_oidc_code(code)
|
||||
{:code, _} ->
|
||||
render(conn, :error, description: "Не удалось найти временный код")
|
||||
|
||||
{access_token, refresh_token} = Accounts.generate_oauth_tokens(code.user)
|
||||
{:uri, _} ->
|
||||
render(conn, :error, description: "Redirect URI не совпадает с изначальным значением")
|
||||
|
||||
id_token = IDToken.build_id_token(code.user, oidc_app.client_id)
|
||||
{:ok, signed_id_token} = Token.sign(id_token, client_secret)
|
||||
{:app, _} ->
|
||||
render(conn, :error, description: "Приложение не найдено или отключено")
|
||||
|
||||
render(conn, :token,
|
||||
access_token: Base.url_encode64(access_token),
|
||||
refresh_token: Base.url_encode64(refresh_token),
|
||||
id_token: signed_id_token
|
||||
)
|
||||
{:code_ref, _} ->
|
||||
render(conn, :error, description: "Временный код выдан для другого приложения")
|
||||
end
|
||||
end
|
||||
|
||||
def openid_discovery(conn, _params) do
|
||||
|
|
|
@ -21,4 +21,10 @@ defmodule ComfycampWeb.OauthJSON do
|
|||
claims_supported: ["sub", "email", "preferred_username"]
|
||||
}
|
||||
end
|
||||
|
||||
def error(assigns) do
|
||||
%{
|
||||
description: assigns["description"]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue