Apply bypass consent option to trunk (#1089)

This commit is contained in:
Clément Oudot 2016-09-27 13:23:29 +00:00
parent 29453547e6
commit 91b7ac93b1
10 changed files with 141 additions and 111 deletions

View File

@ -170,6 +170,7 @@ sub defaultValues {
'name' => 'cn'
},
'oidcRPMetaDataOptionsAccessTokenExpiration' => 3600,
'oidcRPMetaDataOptionsBypassConsent' => 0,
'oidcRPMetaDataOptionsIDTokenExpiration' => 3600,
'oidcRPMetaDataOptionsIDTokenSignAlg' => 'HS512',
'oidcRPStateTimeout' => 600,

View File

@ -1530,6 +1530,10 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
'default' => 3600,
'type' => 'int'
},
'oidcRPMetaDataOptionsBypassConsent' => {
'default' => 0,
'type' => 'bool'
},
'oidcRPMetaDataOptionsClientID' => {
'type' => 'text'
},

View File

@ -2411,8 +2411,9 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
{ type => 'int', default => 3600 },
oidcRPMetaDataOptionsAccessTokenExpiration =>
{ type => 'int', default => 3600 },
oidcRPMetaDataOptionsRedirectUris => { type => 'text', },
oidcRPMetaDataOptionsExtraClaims => { type => 'keyTextContainer', },
oidcRPMetaDataOptionsRedirectUris => { type => 'text', },
oidcRPMetaDataOptionsExtraClaims => { type => 'keyTextContainer', },
oidcRPMetaDataOptionsBypassConsent => { type => 'bool', default => 0 },
};
}

View File

@ -193,6 +193,7 @@ sub cTrees {
'oidcRPMetaDataOptionsIDTokenExpiration',
'oidcRPMetaDataOptionsAccessTokenExpiration',
'oidcRPMetaDataOptionsRedirectUris',
'oidcRPMetaDataOptionsBypassConsent',
'oidcRPMetaDataOptionsExtraClaims'
]
},

View File

@ -25,7 +25,7 @@ our $doubleHashKeys = 'issuerDBGetParameters';
our $simpleHashKeys = '(?:(?:g(?:r(?:antSessionRule|oup)|lobalStorageOption|oogleExportedVar)|l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar)|ca(?:s(?:StorageOption|Attribute)|ptchaStorageOption)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|p(?:ersistentStorageOption|ortalSkinRule)|re(?:moteGlobalStorageOption|loadUrl)|notificationStorageOption|CASproxiedService|macro)s|o(?:idcS(?:erviceMetaDataAuthnContext|torageOptions)|penIdExportedVars)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember)|a(?:uthChoiceModules|pplicationList))';
our $specialNodeKeys = '(?:(?:saml(?:ID|S)|oidc[OR])PMetaDataNode|virtualHost)s';
our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)|heckJWTSignature|onfigurationURI)|TokenEndpointAuthMethod|(?:JWKSTimeou|Promp)t|I(?:DTokenMaxAge|con)|S(?:toreIDToken|cope)|U(?:iLocales|seNonce)|Display(?:Name)?|AcrValues|MaxAge)|ExportedVars|J(?:SON|WKS))';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:I(?:DToken(?:Expiration|SignAlg)|con)|(?:RedirectUri|ExtraClaim)s|AccessTokenExpiration|Client(?:Secret|ID)|DisplayName|UserIDAttr)|ExportedVars)';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:I(?:DToken(?:Expiration|SignAlg)|con)|(?:RedirectUri|ExtraClaim)s|AccessTokenExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|UserIDAttr)|ExportedVars)';
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|S(?:ignS[LS]OMessage|toreSAMLToken|[LS]OBinding)|Check(?:S[LS]OMessageSignature|Conditions)|Re(?:questedAuthnContext|solutionRule)|(?:EncryptionMod|IsPassiv)e|Force(?:Authn|UTF8)|NameIDFormat)|ExportedAttributes|XML)';
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|S(?:essionNotOnOrAfterTimeout|ignS[LS]OMessage)|(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|En(?:ableIDPInitiatedURL|cryptionMode)|ForceUTF8)|ExportedAttributes|XML)';
our $virtualHostKeys = '(?:vhost(?:(?:Aliase|Http)s|Maintenance|Port)|(?:exportedHeader|locationRule)s|post)';

View File

@ -344,6 +344,13 @@ function templates(tpl,key) {
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRedirectUris",
"title" : "oidcRPMetaDataOptionsRedirectUris"
},
{
"default" : 0,
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsBypassConsent",
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsBypassConsent",
"title" : "oidcRPMetaDataOptionsBypassConsent",
"type" : "bool"
},
{
"cnodes" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsExtraClaims",
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsExtraClaims",

File diff suppressed because one or more lines are too long

View File

@ -404,6 +404,7 @@
"oidcRPMetaDataNode": "OpenID Connect Relying Parties",
"oidcRPMetaDataOptions": "Options",
"oidcRPMetaDataOptionsAccessTokenExpiration": "Access token expiration",
"oidcRPMetaDataOptionsBypassConsent": "Bypass consent",
"oidcRPMetaDataOptionsClientID": "Client ID",
"oidcRPMetaDataOptionsClientSecret": "Client secret",
"oidcRPMetaDataOptionsDisplay": "Display",

View File

@ -404,6 +404,7 @@
"oidcRPMetaDataNode": "Clients OpenID Connect",
"oidcRPMetaDataOptions": "Options",
"oidcRPMetaDataOptionsAccessTokenExpiration": "Expiration des jetons d'accès",
"oidcRPMetaDataOptionsBypassConsent": "Contourner le consentement",
"oidcRPMetaDataOptionsClientID": "Identifiant",
"oidcRPMetaDataOptionsClientSecret": "Mot de passe",
"oidcRPMetaDataOptionsDisplay": "Affichage",

View File

@ -874,129 +874,143 @@ sub issuerForAuthUser {
}
# Obtain consent
my $ask_for_consent = 1;
if ( $self->{sessionInfo}->{"_oidc_consent_time_$rp"}
and $self->{sessionInfo}->{"_oidc_consent_scope_$rp"} )
{
$ask_for_consent = 0;
my $consent_time = $self->{sessionInfo}->{"_oidc_consent_time_$rp"};
my $consent_scope =
$self->{sessionInfo}->{"_oidc_consent_scope_$rp"};
my $bypassConsent = $self->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsBypassConsent};
if ($bypassConsent) {
$self->lmLog(
"Consent already given for Relying Party $rp (time: $consent_time, scope: $consent_scope)",
'debug'
);
# Check accepted scope
foreach
my $requested_scope ( split( /\s+/, $oidc_request->{'scope'} ) )
{
if ( $consent_scope =~ /\b$requested_scope\b/ ) {
$self->lmLog( "Scope $requested_scope already accepted",
'debug' );
}
else {
$self->lmLog(
"Scope $requested_scope was not previously accepted",
'debug' );
$ask_for_consent = 1;
last;
}
}
# Check prompt parameter
$ask_for_consent = 1 if ( $prompt =~ /\bconsent\b/ );
"Consent is disabled for RP $rp, user will not be prompted",
'debug' );
}
if ($ask_for_consent) {
if ( $self->param('confirm') == 1 ) {
$self->updatePersistentSession(
{ "_oidc_consent_time_$rp" => time } );
$self->updatePersistentSession(
{
"_oidc_consent_scope_$rp" => $oidc_request->{'scope'}
}
);
$self->lmLog( "Consent given for Relying Party $rp", 'debug' );
}
elsif ( $self->param('confirm') == -1 ) {
$self->lmLog( "User refused consent for Relying party $rp",
'debug' );
$self->returnRedirectError(
$oidc_request->{'redirect_uri'},
"consent_required",
"consent not given",
undef,
$oidc_request->{'state'},
( $flow ne "authorizationcode" )
);
}
else {
$self->lmLog( "Obtain user consent for Relying Party $rp",
'debug' );
else {
my $ask_for_consent = 1;
if ( $self->{sessionInfo}->{"_oidc_consent_time_$rp"}
and $self->{sessionInfo}->{"_oidc_consent_scope_$rp"} )
{
$ask_for_consent = 0;
my $consent_time =
$self->{sessionInfo}->{"_oidc_consent_time_$rp"};
my $consent_scope =
$self->{sessionInfo}->{"_oidc_consent_scope_$rp"};
# Return error if prompt is none
if ( $prompt =~ /\bnone\b/ ) {
$self->lmLog( "Consent is needed but prompt is none",
$self->lmLog(
"Consent already given for Relying Party $rp (time: $consent_time, scope: $consent_scope)",
'debug'
);
# Check accepted scope
foreach my $requested_scope (
split( /\s+/, $oidc_request->{'scope'} ) )
{
if ( $consent_scope =~ /\b$requested_scope\b/ ) {
$self->lmLog( "Scope $requested_scope already accepted",
'debug' );
}
else {
$self->lmLog(
"Scope $requested_scope was not previously accepted",
'debug'
);
$ask_for_consent = 1;
last;
}
}
# Check prompt parameter
$ask_for_consent = 1 if ( $prompt =~ /\bconsent\b/ );
}
if ($ask_for_consent) {
if ( $self->param('confirm') == 1 ) {
$self->updatePersistentSession(
{ "_oidc_consent_time_$rp" => time } );
$self->updatePersistentSession(
{
"_oidc_consent_scope_$rp" =>
$oidc_request->{'scope'}
}
);
$self->lmLog( "Consent given for Relying Party $rp",
'debug' );
}
elsif ( $self->param('confirm') == -1 ) {
$self->lmLog( "User refused consent for Relying party $rp",
'debug' );
$self->returnRedirectError(
$oidc_request->{'redirect_uri'},
"consent_required",
"consent required",
"consent not given",
undef,
$oidc_request->{'state'},
( $flow ne "authorizationcode" )
);
}
else {
$self->lmLog( "Obtain user consent for Relying Party $rp",
'debug' );
my $display_name = $self->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsDisplayName};
my $icon = $self->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsIcon};
my $img_src;
my $portalPath = $self->{portal};
$portalPath =~ s#^https?://[^/]+/?#/#;
$portalPath =~ s#[^/]+\.pl$##;
if ($icon) {
$img_src =
( $icon =~ m#^https?://# )
? $icon
: $portalPath . "skins/common/" . $icon;
}
$self->info('<div class="oidc_consent_message">');
$self->info( '<img src="' . $img_src . '" />' ) if $img_src;
$self->info( '<h3>'
. sprintf( $self->msg(PM_OIDC_CONSENT), $display_name )
. '</h3>' );
$self->info('<ul>');
foreach my $requested_scope (
split( /\s/, $oidc_request->{'scope'} ) )
{
my $message;
my $scope_messages = {
openid => PM_OIDC_SCOPE_OPENID,
profile => PM_OIDC_SCOPE_PROFILE,
email => PM_OIDC_SCOPE_EMAIL,
address => PM_OIDC_SCOPE_ADDRESS,
phone => PM_OIDC_SCOPE_PHONE,
};
if ( $scope_messages->{$requested_scope} ) {
$message =
$self->msg( $scope_messages->{$requested_scope} );
# Return error if prompt is none
if ( $prompt =~ /\bnone\b/ ) {
$self->lmLog( "Consent is needed but prompt is none",
'debug' );
$self->returnRedirectError(
$oidc_request->{'redirect_uri'},
"consent_required",
"consent required",
undef,
$oidc_request->{'state'},
( $flow ne "authorizationcode" )
);
}
else {
$message = $self->msg(PM_OIDC_SCOPE_OTHER) . " "
. $requested_scope;
my $display_name = $self->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsDisplayName};
my $icon = $self->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsIcon};
my $img_src;
my $portalPath = $self->{portal};
$portalPath =~ s#^https?://[^/]+/?#/#;
$portalPath =~ s#[^/]+\.pl$##;
if ($icon) {
$img_src =
( $icon =~ m#^https?://# )
? $icon
: $portalPath . "skins/common/" . $icon;
}
$self->info("<li>$message</li>");
$self->info('<div class="oidc_consent_message">');
$self->info( '<img src="' . $img_src . '" />' ) if $img_src;
$self->info( '<h3>'
. sprintf( $self->msg(PM_OIDC_CONSENT),
$display_name )
. '</h3>' );
$self->info('<ul>');
foreach my $requested_scope (
split( /\s/, $oidc_request->{'scope'} ) )
{
my $message;
my $scope_messages = {
openid => PM_OIDC_SCOPE_OPENID,
profile => PM_OIDC_SCOPE_PROFILE,
email => PM_OIDC_SCOPE_EMAIL,
address => PM_OIDC_SCOPE_ADDRESS,
phone => PM_OIDC_SCOPE_PHONE,
};
if ( $scope_messages->{$requested_scope} ) {
$message =
$self->msg( $scope_messages->{$requested_scope} );
}
else {
$message = $self->msg(PM_OIDC_SCOPE_OTHER) . " "
. $requested_scope;
}
$self->info("<li>$message</li>");
}
$self->info('</ul>');
$self->info('</div>');
$self->{activeTimer} = 0;
return PE_CONFIRM;
}
$self->info('</ul>');
$self->info('</div>');
$self->{activeTimer} = 0;
return PE_CONFIRM;
}
}