Permit disabling automatic sending of prompt=login to the OIDC provider (#616)

Adds a new `prompt_for_login` configuration file setting in the `[auth_openidconnect`]` block (defaults to true for backward compatibility) which can be used to avoid advising the OpenID Connect provider to prompt for login details even if the user has a valid provider login session. Resolves #614.
This commit is contained in:
Ximon Eighteen
2021-08-03 11:20:38 +02:00
committed by GitHub
parent 45977aa136
commit 47d23f87a7
5 changed files with 55 additions and 11 deletions
+16 -3
View File
@@ -164,6 +164,7 @@
# insecure = false
# extra_login_scopes = ["...", ...]
# extra_login_params = ["...", ...]
# prompt_for_login = false
# logout_url = "..."
#
# [auth_openidconnect.claims]
@@ -218,14 +219,26 @@
# Connect Core 1.0 specification [*2] lists various
# parameters that can be sent but the supported set
# varies by provider. The prompt=login parameter is
# automatically sent by the provider and thus does
# not need to be provided using this setting. Can
# also be specified as a separate TOML table, e.g.:
# automatically sent by the provider (though this
# behavior can be disabled, see prompt_for_login
# below) and thus does not need to be provided
# using this setting. Can also be specified as a
# separate TOML table, e.g.:
#
# [openid_connect.extra_login_params]
# display=popup
# ui_locales="fr-CA fr en"
#
# prompt_for_login No Defaults to true. Setting this to false will
# disable the default behaviour of sending the
# prompt=login parameter to the provider. This
# also allows a different prompt=<value> to be
# specified using extra_login_params, from the set
# defined in Section 3.1.2.1. Authentication
# Request in the OpenID Connect Core 1.0
# specification [*2]: "none", "login", "consent"
# or "select_account".
#
# logout_url No A URL to direct the browser to redirect the user
# to in order to logout. Ideally this is not needed
# as the provider OpenID Connect Discovery response
@@ -22,12 +22,21 @@ pub struct ConfigAuthOpenIDConnect {
#[serde(default)]
pub extra_login_params: HashMap<String, String>,
#[serde(default = "default_prompt_for_login")]
pub prompt_for_login: bool,
#[serde(default)]
pub logout_url: Option<String>,
#[serde(default)]
pub insecure: bool,
}
fn default_prompt_for_login() -> bool {
// On by default for backward compatability. See: https://github.com/NLnetLabs/krill/issues/614
true
}
#[derive(Clone, Debug, Deserialize)]
pub struct ConfigAuthOpenIDConnectClaim {
pub source: Option<ConfigAuthOpenIDConnectClaimSource>,
@@ -1304,6 +1304,10 @@ impl AuthProvider for OpenIDConnectAuthProvider {
|| Nonce::new(base64::encode_config(nonce_hash, base64::URL_SAFE_NO_PAD)),
);
// This unwrap is safe as we check in new() that the OpenID Connect
// config exists.
let oidc_conf = self.oidc_conf()?;
// From https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest:
// "prompt: login - The Authorization Server SHOULD prompt the
// End-User for re-authentication. If it cannot re-authenticate the
@@ -1313,7 +1317,11 @@ impl AuthProvider for OpenIDConnectAuthProvider {
// to specify who to login as, we don't want the provider somehow
// automatically completing the login process because it has some notion
// of an existing login session.
request = request.add_prompt(CoreAuthPrompt::Login);
// https://github.com/NLnetLabs/krill/issues/614
if oidc_conf.prompt_for_login {
request = request.add_prompt(CoreAuthPrompt::Login);
}
// The "openid" scope that OpenID Connect: providers are required to
// check for is sent automatically by the openidconnect crate. We can
@@ -1333,10 +1341,6 @@ impl AuthProvider for OpenIDConnectAuthProvider {
// TODO: use request.set_pkce_challenge() ?
// This unwrap is safe as we check in new() that the OpenID Connect
// config exists.
let oidc_conf = self.oidc_conf()?;
for scope in &oidc_conf.extra_login_scopes {
request = request.add_scope(Scope::new(scope.clone()));
}
+16 -3
View File
@@ -418,6 +418,7 @@ service_uri = "https://localhost:3001/"
# insecure = false
# extra_login_scopes = ["...", ...]
# extra_login_params = ["...", ...]
# prompt_for_login = false
# logout_url = "..."
#
# [auth_openidconnect.claims]
@@ -472,14 +473,26 @@ service_uri = "https://localhost:3001/"
# Connect Core 1.0 specification [*2] lists various
# parameters that can be sent but the supported set
# varies by provider. The prompt=login parameter is
# automatically sent by the provider and thus does
# not need to be provided using this setting. Can
# also be specified as a separate TOML table, e.g.:
# automatically sent by the provider (though this
# behavior can be disabled, see prompt_for_login
# below) and thus does not need to be provided
# using this setting. Can also be specified as a
# separate TOML table, e.g.:
#
# [openid_connect.extra_login_params]
# display=popup
# ui_locales="fr-CA fr en"
#
# prompt_for_login No Defaults to true. Setting this to false will
# disable the default behaviour of sending the
# prompt=login parameter to the provider. This
# also allows a different prompt=<value> to be
# specified using extra_login_params, from the set
# defined in Section 3.1.2.1. Authentication
# Request in the OpenID Connect Core 1.0
# specification [*2]: "none", "login", "consent"
# or "select_account".
#
# logout_url No A URL to direct the browser to redirect the user
# to in order to logout. Ideally this is not needed
# as the provider OpenID Connect Discovery response
@@ -16,6 +16,11 @@ issuer_url = "https://localhost:1818"
client_id = "client-id-123"
client_secret = "some-secret"
# custom prompt= behaviour is ignored by the OpenID Connect mock, this is just here to exercise the config parser and
# for manually observing that the prompt query param in the requests to the mock change as expected.
prompt_for_login = false
extra_login_params = { prompt = "none" }
[auth_openidconnect.claims]
# recap_demo = { jmespath = "recap(nonce, '([A-Z]+)')", dest = "boing" }
# resub_demo = { jmespath = "resub(nonce, '^[A-Z]+.*', '<replaced>')" }