aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Arter <davea@mysociety.org>2020-05-13 16:41:26 +0100
committerDave Arter <davea@mysociety.org>2020-07-02 14:38:49 +0100
commitc505cbca2576f9e658692d8e1c512f645069985a (patch)
tree892b5c3de8288999f7a9e2ec34a0e7a93437aa99
parent3b958bc30c5ccb6ea3143c08d1ca65dc0bf4b9bc (diff)
OIDC scope/token parsing improvements
- Cobrand config can now specify custom scope and other params e.g. G Suite supports per-domain customisation and the ‘prompt’ param to always ask the user to select the account they want to login with. - Token may have an ‘name’ claim instead of needing to concat given_/family_name claims
-rw-r--r--CHANGELOG.md1
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth/Social.pm21
2 files changed, 17 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93292785c..e22d3cc63 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
- Skip accounts without email when sending inactive emails.
- Include file extensions in Dropzone accepted photo config.
- Fix photo orientation in modern browsers.
+ - Improve compatibility with G Suite OpenID Connect authentication. #3032
- Admin improvements:
- Display user name/email for contributed as reports. #2990
- Interface for enabling anonymous reports for certain categories. #2989
diff --git a/perllib/FixMyStreet/App/Controller/Auth/Social.pm b/perllib/FixMyStreet/App/Controller/Auth/Social.pm
index 54cf35315..2468cfad2 100644
--- a/perllib/FixMyStreet/App/Controller/Auth/Social.pm
+++ b/perllib/FixMyStreet/App/Controller/Auth/Social.pm
@@ -179,7 +179,9 @@ sub oidc_sign_in : Private {
my ( $self, $c ) = @_;
$c->detach( '/page_error_403_access_denied', [] ) if FixMyStreet->config('SIGNUPS_DISABLED');
- $c->detach( '/page_error_400_bad_request', [] ) unless $c->cobrand->feature('oidc_login');
+
+ my $cfg = $c->cobrand->feature('oidc_login');
+ $c->detach( '/page_error_400_bad_request', [] ) unless $cfg;
my $oidc = $c->forward('oidc');
my $nonce = $self->generate_nonce();
@@ -190,6 +192,15 @@ sub oidc_sign_in : Private {
extra => {
response_mode => 'form_post',
nonce => $nonce,
+ # auth_extra_params provides a way to pass custom parameters
+ # to the OIDC endpoint for the intial authentication request.
+ # This allows, for example, a custom scope to be used,
+ # or the `hd` parameter which customises the appearance of
+ # the login form.
+ # This is primarily useful for Google G Suite authentication - see
+ # available parameters here:
+ # https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters
+ %{ $cfg->{auth_extra_params} || {} } ,
},
);
@@ -201,14 +212,14 @@ sub oidc_sign_in : Private {
# The OIDC endpoint may require a specific URI to be called to log the user
# out when they log out of FMS.
- if ( my $redirect_uri = $c->cobrand->feature('oidc_login')->{logout_uri} ) {
+ if ( my $redirect_uri = $cfg->{logout_uri} ) {
$redirect_uri .= "?post_logout_redirect_uri=";
$redirect_uri .= URI::Escape::uri_escape( $c->uri_for('/auth/sign_out') );
$oauth{logout_redirect_uri} = $redirect_uri;
}
# The OIDC endpoint may provide a specific URI for changing the user's password.
- if ( my $password_change_uri = $c->cobrand->feature('oidc_login')->{password_change_uri} ) {
+ if ( my $password_change_uri = $cfg->{password_change_uri} ) {
$oauth{change_password_uri} = $oidc->uri_to_redirect(
uri => $password_change_uri,
redirect_uri => $c->uri_for('/auth/OIDC'),
@@ -295,9 +306,9 @@ sub oidc_callback: Path('/auth/OIDC') : Args(0) {
$c->detach('/page_error_500_internal_error', ['invalid id_token']) unless $id_token->payload->{nonce} eq $c->session->{oauth}{nonce};
# Some claims need parsing into a friendlier format
- # XXX check how much of this is Westminster/Azure-specific
- my $name = join(" ", $id_token->payload->{given_name}, $id_token->payload->{family_name});
+ my $name = $id_token->payload->{name} || join(" ", $id_token->payload->{given_name}, $id_token->payload->{family_name});
my $email = $id_token->payload->{email};
+
# WCC Azure provides a single email address as an array for some reason
my $emails = $id_token->payload->{emails};
if ($emails && @$emails) {