feat(oidc): support the PKCE extension

This commit is contained in:
firest 2024-06-20 22:57:00 +08:00
parent 5e2693c9b4
commit 9c0df3c0a8
3 changed files with 29 additions and 10 deletions

View File

@ -33,6 +33,7 @@
<<"content-type">> => <<"text/plain">>
}).
-define(REDIRECT_BODY, <<"Redirecting...">>).
-define(PKCE_VERIFIER_LEN, 60).
%%------------------------------------------------------------------------------
%% Hocon Schema
@ -84,6 +85,11 @@ fields(oidc) ->
?HOCON(emqx_schema:timeout_duration_ms(), #{
desc => ?DESC(session_expiry),
default => <<"30s">>
})},
{require_pkce,
?HOCON(boolean(), #{
desc => ?DESC(require_pkce),
default => false
})}
];
fields(login) ->
@ -133,25 +139,27 @@ login(
config := #{
clientid := ClientId,
secret := Secret,
scopes := Scopes
scopes := Scopes,
require_pkce := RequirePKCE
}
} = Cfg
) ->
Nonce = emqx_dashboard_sso_oidc_session:random_bin(),
Data = #{nonce => Nonce},
Opts = maybe_require_pkce(RequirePKCE, #{
scopes => Scopes,
nonce => Nonce,
redirect_uri => emqx_dashboard_sso_oidc_api:make_callback_url(Cfg)
}),
Data = maps:with([nonce, require_pkce, pkce_verifier], Opts),
State = emqx_dashboard_sso_oidc_session:new(Data),
case
oidcc:create_redirect_url(
?PROVIDER_SVR_NAME,
ClientId,
Secret,
#{
scopes => Scopes,
state => State,
nonce => Nonce,
redirect_uri => emqx_dashboard_sso_oidc_api:make_callback_url(Cfg)
}
Opts#{state => State}
)
of
{ok, [Base, Delimiter, Params]} ->
@ -164,3 +172,11 @@ login(
convert_certs(_Dir, Conf) ->
Conf.
maybe_require_pkce(false, Opts) ->
Opts;
maybe_require_pkce(true, Opts) ->
Opts#{
require_pkce => true,
pkce_verifier => emqx_dashboard_sso_oidc_session:random_bin(?PKCE_VERIFIER_LEN)
}.

View File

@ -115,7 +115,7 @@ ensure_oidc_state(#{<<"state">> := State} = QS, Cfg) ->
retrieve_token(
#{<<"code">> := Code},
#{name := Name, config := #{clientid := ClientId, secret := Secret}} = Cfg,
#{nonce := Nonce} = _Data
Data
) ->
case
oidcc:retrieve_token(
@ -123,7 +123,7 @@ retrieve_token(
Name,
ClientId,
Secret,
#{redirect_uri => make_callback_url(Cfg), nonce => Nonce}
Data#{redirect_uri => make_callback_url(Cfg)}
)
of
{ok, Token} ->

View File

@ -21,4 +21,7 @@ dashboard_addr.desc:
session_expiry.desc:
"""The valid time span for an OIDC `state`, the default is `30s`, if the code response returned by the authorization server exceeds this time span, it will be treated as invalid."""
require_pkce.desc:
"""Whether to require PKCE when getting the token."""
}