From b14ec43a880e979f8eaf6c4a9c457932a505bfb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Oudot?= Date: Mon, 30 Mar 2015 12:58:56 +0000 Subject: [PATCH] Check redirect_uri (#184) --- .../lib/Lemonldap/NG/Manager/_Struct.pm | 25 ++++-- .../lib/Lemonldap/NG/Manager/_i18n.pm | 82 ++++++++++--------- .../NG/Portal/IssuerDBOpenIDConnect.pm | 24 ++++++ 3 files changed, 87 insertions(+), 44 deletions(-) diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm index 6d7767b4e..6542e5436 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm @@ -316,8 +316,9 @@ sub cstruct { %$h, oidcRPMetaDataNode => { $k2 => { - _nodes => - [qw(oidcRPMetaDataExportedVars oidcRPMetaDataOptions)], + _nodes => [ + qw(oidcRPMetaDataExportedVars oidcRPMetaDataOptions) + ], oidcRPMetaDataExportedVars => { _nodes => ["hash:/oidcRPMetaDataExportedVars/$k2:vars:btext"], @@ -325,24 +326,36 @@ sub cstruct { }, oidcRPMetaDataOptions => { _nodes => [ - qw(oidcRPMetaDataOptionsClientID oidcRPMetaDataOptionsClientSecret oidcRPMetaDataOptionsUserIDAttr oidcRPMetaDataOptionsDisplayName oidcRPMetaDataOptionsIcon oidcRPMetaDataOptionsIDTokenSignAlg oidcRPMetaDataOptionsIDTokenExpiration oidcRPMetaDataOptionsAccessTokenExpiration) + qw(oidcRPMetaDataOptionsAuthentication oidcRPMetaDataOptionsDisplay oidcRPMetaDataOptionsUserIDAttr oidcRPMetaDataOptionsIDTokenSignAlg oidcRPMetaDataOptionsIDTokenExpiration oidcRPMetaDataOptionsAccessTokenExpiration oidcRPMetaDataOptionsRedirectUris) + ], +oidcRPMetaDataOptionsAuthentication => { + _nodes => [ + qw(oidcRPMetaDataOptionsClientID oidcRPMetaDataOptionsClientSecret) ], oidcRPMetaDataOptionsClientID => "text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsClientID", oidcRPMetaDataOptionsClientSecret => "password:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsClientSecret", - oidcRPMetaDataOptionsUserIDAttr => -"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsUserIDAttr", + }, + oidcRPMetaDataOptionsDisplay => { + _nodes => [ + qw(oidcRPMetaDataOptionsDisplayName oidcRPMetaDataOptionsIcon) + ], oidcRPMetaDataOptionsDisplayName => "text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsDisplayName", oidcRPMetaDataOptionsIcon => "text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsIcon", + }, + oidcRPMetaDataOptionsUserIDAttr => +"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsUserIDAttr", oidcRPMetaDataOptionsIDTokenSignAlg => "text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsIDTokenSignAlg", oidcRPMetaDataOptionsIDTokenExpiration => "int:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsIDTokenExpiration", oidcRPMetaDataOptionsAccessTokenExpiration => "int:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsAccessTokenExpiration", + oidcRPMetaDataOptionsRedirectUris => +"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsRedirectUris", }, }, }, @@ -1603,7 +1616,7 @@ sub struct { oidcServiceMetaDataSecurity => { _nodes => - [ qw(oidcServicePrivateKeySig oidcServicePublicKeySig) ], + [qw(oidcServicePrivateKeySig oidcServicePublicKeySig)], oidcServicePrivateKeySig => 'filearea:/oidcServicePrivateKeySig', oidcServicePublicKeySig => 'filearea:/oidcServicePublicKeySig', diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm index e0ce4ab9e..4bc564444 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm @@ -290,12 +290,15 @@ sub en { oidcRPMetaDataNode => 'OpenID Connect Relying Parties', oidcRPMetaDataOptions => 'Options', oidcRPMetaDataOptionsAccessTokenExpiration => 'Access Token expiration', + oidcRPMetaDataOptionsAuthentication => 'Authentication', oidcRPMetaDataOptionsClientID => 'Client ID', oidcRPMetaDataOptionsClientSecret => 'Client secret', + oidcRPMetaDataOptionsDisplay => 'Display', oidcRPMetaDataOptionsDisplayName => 'Display name', oidcRPMetaDataOptionsIcon => 'Logo', oidcRPMetaDataOptionsIDTokenExpiration => 'ID Token expiration', oidcRPMetaDataOptionsIDTokenSignAlg => 'ID Token signature algorithm', + oidcRPMetaDataOptionsRedirectUris => 'Redirection addresses', oidcRPMetaDataOptionsUserIDAttr => 'User ID attribute', oidcRPStateTimeout => 'State session timeout', oidcServiceMetaData => 'OpenID Connect Service', @@ -851,48 +854,51 @@ sub fr { oidcRPMetaDataOptions => 'Options', oidcRPMetaDataOptionsAccessTokenExpiration => "Expiration des jetons d'accès", - oidcRPMetaDataOptionsClientID => 'Identifiant', - oidcRPMetaDataOptionsClientSecret => 'Mot de passe', - oidcRPMetaDataOptionsDisplayName => 'Nom d\'affichage', - oidcRPMetaDataOptionsIcon => 'Logo', + oidcRPMetaDataOptionsAuthentication => 'Authentification', + oidcRPMetaDataOptionsClientID => 'Identifiant', + oidcRPMetaDataOptionsClientSecret => 'Mot de passe', + oidcRPMetaDataOptionsDisplay => 'Affichage', + oidcRPMetaDataOptionsDisplayName => 'Nom d\'affichage', + oidcRPMetaDataOptionsIcon => 'Logo', oidcRPMetaDataOptionsIDTokenExpiration => "Expiration des jetons d'identité", oidcRPMetaDataOptionsIDTokenSignAlg => "Algorithme de signature des jetons d'identité", - oidcRPMetaDataOptionsUserIDAttr => "Attribut de l'identifiant", - oidcRPStateTimeout => 'Durée d\'une session state', - oidcServiceMetaData => "Service OpenID Connect", - oidcServiceMetaDataAuthorizeURI => "Autorisation", - oidcServiceMetaDataEndPoints => "Points d'accès", - oidcServiceMetaDataIssuer => "Identifiant du fournisseur", - oidcServiceMetaDataJWKSURI => 'JWKS', - oidcServiceMetaDataSecurity => 'Sécurité', - oidcServiceMetaDataTokenURI => "Jeton", - oidcServiceMetaDataUserInfoURI => 'Informations Utilisateur', - oidcServicePrivateKeySig => 'Clé privée de signature', - oidcServicePublicKeySig => 'Clé publique de signature', - openIdAttr => 'Identifiant OpenID', - openIdAuthnLevel => 'Niveau d\'authentification', - openIdExportedVars => 'Variables exportées', - openIdIDPList => 'Domaines autorisés', - openIdIssuerSecret => 'Jeton secret', - openIdParams => 'Paramètres OpenID', - openIdSecret => 'Jeton secret', - openIdSreg => 'Associations SREG', - openIdSreg_fullname => 'Nom complet', - openIdSreg_nickname => 'Surnom', - openIdSreg_language => 'Langage', - openIdSreg_postcode => 'Code postal', - openIdSreg_timezone => 'Zone horaire', - openIdSreg_country => 'Pays', - openIdSreg_gender => 'Genre', - openIdSreg_email => 'Email', - openIdSreg_dob => 'Date de naissance', - openIdSPList => 'Domaines autorisés', - passwordDB => 'Module de mot de passe', - passwordManagement => 'Gestion des mots de passe', - persistentSessions => 'Sessions persistantes', - persistentStorage => 'Module Apache::Session', + oidcRPMetaDataOptionsRedirectUris => 'Adresses de redirection', + oidcRPMetaDataOptionsUserIDAttr => "Attribut de l'identifiant", + oidcRPStateTimeout => 'Durée d\'une session state', + oidcServiceMetaData => "Service OpenID Connect", + oidcServiceMetaDataAuthorizeURI => "Autorisation", + oidcServiceMetaDataEndPoints => "Points d'accès", + oidcServiceMetaDataIssuer => "Identifiant du fournisseur", + oidcServiceMetaDataJWKSURI => 'JWKS', + oidcServiceMetaDataSecurity => 'Sécurité', + oidcServiceMetaDataTokenURI => "Jeton", + oidcServiceMetaDataUserInfoURI => 'Informations Utilisateur', + oidcServicePrivateKeySig => 'Clé privée de signature', + oidcServicePublicKeySig => 'Clé publique de signature', + openIdAttr => 'Identifiant OpenID', + openIdAuthnLevel => 'Niveau d\'authentification', + openIdExportedVars => 'Variables exportées', + openIdIDPList => 'Domaines autorisés', + openIdIssuerSecret => 'Jeton secret', + openIdParams => 'Paramètres OpenID', + openIdSecret => 'Jeton secret', + openIdSreg => 'Associations SREG', + openIdSreg_fullname => 'Nom complet', + openIdSreg_nickname => 'Surnom', + openIdSreg_language => 'Langage', + openIdSreg_postcode => 'Code postal', + openIdSreg_timezone => 'Zone horaire', + openIdSreg_country => 'Pays', + openIdSreg_gender => 'Genre', + openIdSreg_email => 'Email', + openIdSreg_dob => 'Date de naissance', + openIdSPList => 'Domaines autorisés', + passwordDB => 'Module de mot de passe', + passwordManagement => 'Gestion des mots de passe', + persistentSessions => 'Sessions persistantes', + persistentStorage => 'Module Apache::Session', persistentStorageOptions => 'Paramètres du module Apache::Session', port => 'Port', portal => 'URL', diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBOpenIDConnect.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBOpenIDConnect.pm index 63087f1f9..4ad3ee5fd 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBOpenIDConnect.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBOpenIDConnect.pm @@ -521,6 +521,30 @@ sub issuerForAuthUser { $self->lmLog( "Client id $client_id match RP $rp", 'debug' ); } + # Check redirect_uri + my $redirect_uri = $oidc_request->{'redirect_uri'}; + my $redirect_uris = $self->{oidcRPMetaDataOptions}->{$rp} + ->{oidcRPMetaDataOptionsRedirectUris}; + + if ($redirect_uris) { + my $redirect_uri_allowed = 0; + foreach ( split( /\s+/, $redirect_uris ) ) { + $redirect_uri_allowed = 1 if $redirect_uri eq $_; + } + unless ($redirect_uri_allowed) { + $self->lmLog( "Redirect URI $redirect_uri not allowed", + 'error' ); + $self->returnRedirectError( + $oidc_request->{'redirect_uri'}, + "invalid_request", + "redirect_uri $redirect_uri not allowed", + undef, + $oidc_request->{'state'}, + ( $flow ne "authorizationcode" ) + ); + } + } + # Check id_token_hint my $id_token_hint = $oidc_request->{'id_token_hint'}; if ($id_token_hint) {