Add an option to return claims in ID token

register-approval
Maxime Besson 6 years ago
parent 5b2e6f7d9f
commit 713737c11f
  1. 2
      lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Constants.pm
  2. 2
      lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/ReConstants.pm
  3. 3
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm
  4. 3
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm
  5. 1
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/CTrees.pm
  6. 6
      lemonldap-ng-manager/site/htdocs/static/js/conftree.js
  7. 2
      lemonldap-ng-manager/site/htdocs/static/js/conftree.min.js
  8. 2
      lemonldap-ng-manager/site/htdocs/static/js/conftree.min.js.map
  9. 1
      lemonldap-ng-manager/site/htdocs/static/languages/ar.json
  10. 1
      lemonldap-ng-manager/site/htdocs/static/languages/de.json
  11. 1
      lemonldap-ng-manager/site/htdocs/static/languages/en.json
  12. 1
      lemonldap-ng-manager/site/htdocs/static/languages/fr.json
  13. 1
      lemonldap-ng-manager/site/htdocs/static/languages/it.json
  14. 1
      lemonldap-ng-manager/site/htdocs/static/languages/vi.json
  15. 1
      lemonldap-ng-manager/site/htdocs/static/languages/zh.json
  16. 38
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenIDConnect.pm
  17. 26
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/OpenIDConnect.pm
  18. 9
      lemonldap-ng-portal/t/32-OIDC-Offline-Session.t
  19. 7
      lemonldap-ng-portal/t/32-OIDC-Refresh-Token.t

@ -24,7 +24,7 @@ use constant MANAGERSECTION => "manager";
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
use constant APPLYSECTION => "apply";
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node)|S(?:erviceMetaDataAuthnContext|torageOptions))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions)|A(?:ppMetaData(?:(?:ExportedVar|Option)s|Node)|ttributes))|(?:ustomAddParam|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|rsEnabled)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?)?|y(?:Deleted|Other))|AjaxHook)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|d(?:isablePersistentStorage|biDynamicHashEnabled|ontCompactConf)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|br(?:owsersDontStorePassword|uteForceProtection)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|rsEnabled)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?)?|y(?:Deleted|Other))|AjaxHook)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|d(?:isablePersistentStorage|biDynamicHashEnabled|ontCompactConf)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|br(?:owsersDontStorePassword|uteForceProtection)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

@ -27,7 +27,7 @@ our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaData
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:UserAttribut|Servic|Rul)e|ExportedVars)';
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)';
our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)|heckJWTSignature|onfigurationURI)|S(?:toreIDToken|ortNumber|cope)|TokenEndpointAuthMethod|(?:JWKSTimeou|Promp)t|I(?:DTokenMaxAge|con)|U(?:iLocales|seNonce)|Display(?:Name)?|AcrValues|MaxAge)|ExportedVars|J(?:SON|WKS))';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:(?:uthorizationCode|ccessToken)Expiration|llowOffline)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|I(?:DToken(?:Expiration|SignAlg)|con)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|ExportedVars)';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:(?:uthorizationCode|ccessToken)Expiration|llowOffline)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|ExportedVars)';
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|UserAttribut|DisplayNam)e|S(?:ignS[LS]OMessage|toreSAMLToken|[LS]OBinding|ortNumber)|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|Force(?:Authn|UTF8)|I(?:sPassive|con)|NameIDFormat)|ExportedAttributes|XML)';
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|S(?:essionNotOnOrAfterTimeout|ignS[LS]OMessage)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|ForceUTF8)|ExportedAttributes|XML)';
our $virtualHostKeys = '(?:vhost(?:A(?:uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';

@ -2014,6 +2014,9 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'oidcRPMetaDataOptionsIDTokenExpiration' => {
'type' => 'int'
},
'oidcRPMetaDataOptionsIDTokenForceClaims' => {
'type' => 'bool'
},
'oidcRPMetaDataOptionsIDTokenSignAlg' => {
'default' => 'HS512',
'select' => [ {

@ -3740,9 +3740,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
default => 'HS512',
},
oidcRPMetaDataOptionsIDTokenExpiration => { type => 'int' },
oidcRPMetaDataOptionsIDTokenForceClaims => { type => 'bool' },
oidcRPMetaDataOptionsAccessTokenExpiration => { type => 'int' },
oidcRPMetaDataOptionsAuthorizationCodeExpiration => { type => 'int' },
oidcRPMetaDataOptionsOfflineSessionExpiration => { type => 'int' },
oidcRPMetaDataOptionsOfflineSessionExpiration => { type => 'int' },
oidcRPMetaDataOptionsRedirectUris => { type => 'text', },
oidcRPMetaDataOptionsExtraClaims =>
{ type => 'keyTextContainer', default => {} },

@ -203,6 +203,7 @@ sub cTrees {
'oidcRPMetaDataOptionsUserIDAttr',
'oidcRPMetaDataOptionsIDTokenSignAlg',
'oidcRPMetaDataOptionsIDTokenExpiration',
'oidcRPMetaDataOptionsIDTokenForceClaims',
'oidcRPMetaDataOptionsAccessTokenExpiration',
'oidcRPMetaDataOptionsAuthorizationCodeExpiration',
'oidcRPMetaDataOptionsAllowOffline',

@ -478,6 +478,12 @@ function templates(tpl,key) {
"title" : "oidcRPMetaDataOptionsIDTokenExpiration",
"type" : "int"
},
{
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsIDTokenForceClaims",
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsIDTokenForceClaims",
"title" : "oidcRPMetaDataOptionsIDTokenForceClaims",
"type" : "bool"
},
{
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAccessTokenExpiration",
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAccessTokenExpiration",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"شعار",
"oidcRPMetaDataOptionsIDTokenExpiration":" انتهاء صلاحية تعريف التوكن",
"oidcRPMetaDataOptionsIDTokenSignAlg":"خوارزمية توقيع آي دي التوكن",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Force claims to be returned in ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"خاصّيّة المستخدم",

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"Logo",
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Force claims to be returned in ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"Logo",
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Force claims to be returned in ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"Logo",
"oidcRPMetaDataOptionsIDTokenExpiration":"Expiration des jetons d'identité",
"oidcRPMetaDataOptionsIDTokenSignAlg":"Algorithme de signature des jetons d'identité",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Forcer la publication des attributs dans l'ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Expiration des sessions hors-ligne",
"oidcRPMetaDataOptionsRefreshToken":"Utiliser les refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"Attribut de l'utilisateur",

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"Logo",
"oidcRPMetaDataOptionsIDTokenExpiration":"Scadenza ID Token",
"oidcRPMetaDataOptionsIDTokenSignAlg":"Algoritmo di firma di identificazione di Token",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Force claims to be returned in ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Scadenza Refresh Token",
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"Attributo utente",

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"Logo",
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token hết hạn",
"oidcRPMetaDataOptionsIDTokenSignAlg":"Thuật toán chữ ký ID Token",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Force claims to be returned in ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Refresh Token hết hạn",
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"thuộc tính người dùng",

@ -568,6 +568,7 @@
"oidcRPMetaDataOptionsIcon":"Logo",
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
"oidcRPMetaDataOptionsIDTokenForceClaims":"Force claims to be returned in ID Token",
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",

@ -774,7 +774,9 @@ sub run {
$id_token_payload_hash->{'acr'} = $id_token_acr
if $id_token_acr;
if ( $response_type !~ /\btoken\b/ ) {
if ( $response_type !~ /\btoken\b/
|| $self->force_id_claims($rp) )
{
# No access_token
# Claims must be set in id_token
@ -918,7 +920,9 @@ sub run {
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
$id_token_payload_hash->{'c_hash'} = $c_hash if $c_hash;
if ( $response_type !~ /\btoken\b/ ) {
if ( $response_type !~ /\btoken\b/
|| $self->force_id_claims($rp) )
{
# No access_token
# Claims must be set in id_token
@ -1256,6 +1260,17 @@ sub token {
$id_token_payload_hash->{nonce} = $nonce if defined $nonce;
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
if ( $self->force_id_claims($rp) ) {
my $claims =
$self->buildUserInfoResponseFromId( $codeSession->data->{'scope'},
$rp, $codeSession->data->{user_session_id} );
foreach ( keys %$claims ) {
$id_token_payload_hash->{$_} = $claims->{$_}
unless ( $_ eq "sub" );
}
}
# Create ID Token
my $id_token = $self->createIDToken( $id_token_payload_hash, $rp );
@ -1314,11 +1329,12 @@ sub token {
my $access_token;
my $user_id;
my $auth_time;
my $session;
# If this refresh token is tied to a SSO session
if ( $refreshSession->data->{user_session_id} ) {
my $user_session_id = $refreshSession->data->{user_session_id};
my $session = $self->p->getApacheSession($user_session_id);
$session = $self->p->getApacheSession($user_session_id);
unless ($session) {
$self->logger->error("Unable to find user session");
@ -1388,6 +1404,10 @@ sub token {
# Update refresh session
$self->updateRefreshToken( $refreshSession->id, $req->sessionInfo );
$session = $refreshSession;
for ( keys %{ $req->sessionInfo } ) {
$refreshSession->data->{$_} = $req->sessionInfo->{$_};
}
my $user_id_attribute =
$self->conf->{oidcRPMetaDataOptions}->{$rp}
@ -1454,6 +1474,18 @@ sub token {
$id_token_payload_hash->{nonce} = $nonce if defined $nonce;
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
# If we forced sending claims in ID token
if ( $self->force_id_claims($rp) ) {
my $claims =
$self->buildUserInfoResponse( $refreshSession->data->{scope},
$rp, $session );
foreach ( keys %$claims ) {
$id_token_payload_hash->{$_} = $claims->{$_}
unless ( $_ eq "sub" );
}
}
# Create ID Token
my $id_token = $self->createIDToken( $id_token_payload_hash, $rp );

@ -691,17 +691,15 @@ sub getAccessToken {
sub newRefreshToken {
my ( $self, $rp, $info, $offline ) = @_;
my $ttl = $offline ? (
$self->conf->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsOfflineSessionExpiration}
|| $self->conf->{oidcServiceOfflineSessionExpiration}) : $self->conf->{timeout};
return $self->getOpenIDConnectSession(
undef,
"refresh_token",
$ttl,
$info
);
my $ttl =
$offline
? ( $self->conf->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsOfflineSessionExpiration}
|| $self->conf->{oidcServiceOfflineSessionExpiration} )
: $self->conf->{timeout};
return $self->getOpenIDConnectSession( undef, "refresh_token", $ttl,
$info );
}
# Get existing Refresh Token
@ -1669,6 +1667,12 @@ sub validatePKCEChallenge {
return 0;
}
sub force_id_claims {
my ( $self, $rp ) = @_;
return $self->conf->{oidcRPMetaDataOptions}->{$rp}
->{oidcRPMetaDataOptionsIDTokenForceClaims};
}
1;
__END__

@ -52,6 +52,7 @@ my $op = LLNG::Manager::Test->new( {
oidcRPMetaDataOptionsUserIDAttr => "",
oidcRPMetaDataOptionsAccessTokenExpiration => 3600,
oidcRPMetaDataOptionsBypassConsent => 1,
oidcRPMetaDataOptionsIDTokenForceClaims => 1,
}
},
oidcOPMetaDataOptions => {},
@ -151,6 +152,10 @@ ok( $refresh_token, "Got refresh token" );
ok( $id_token, "Got ID token" );
count(3);
my $id_token_payload = JSON::from_json(decode_base64([split /\./, $id_token]->[1]));
is($id_token_payload->{name}, 'Frédéric Accents', 'Found claim in ID token');
count(1);
# Get userinfo
$res = $op->_post(
"/oauth2/userinfo",
@ -198,6 +203,10 @@ ok( $id_token, "Got refreshed ID token" );
ok( !defined $refresh_token, "Refresh token not present" );
count(3);
$id_token_payload = JSON::from_json(decode_base64([split /\./, $id_token]->[1]));
is($id_token_payload->{name}, 'Frédéric Accents', 'Found claim in ID token');
count(1);
## Get userinfo again
ok(
$res = $op->_post(

@ -53,6 +53,7 @@ my $op = LLNG::Manager::Test->new( {
oidcRPMetaDataOptionsAccessTokenExpiration => 1,
oidcRPMetaDataOptionsBypassConsent => 1,
oidcRPMetaDataOptionsRefreshToken => 1,
oidcRPMetaDataOptionsIDTokenForceClaims => 1,
}
},
oidcOPMetaDataOptions => {},
@ -151,6 +152,9 @@ ok( $access_token, "Got access token" );
ok( $refresh_token, "Got refresh token" );
ok( $id_token, "Got ID token" );
my $id_token_payload = JSON::from_json(decode_base64([split /\./, $id_token]->[1]));
is($id_token_payload->{name}, 'Frédéric Accents', 'Found claim in ID token');
# Get userinfo
$res = $op->_post(
"/oauth2/userinfo",
@ -206,6 +210,9 @@ ok( $access_token, "Got refreshed Access token" );
ok( $id_token, "Got refreshed ID token" );
ok( !defined $json->{refresh_token}, "Refresh token not present" );
$id_token_payload = JSON::from_json(decode_base64([split /\./, $id_token]->[1]));
is($id_token_payload->{name}, 'Frédéric Accents', 'Found claim in ID token');
# Try refreshed access token
$res = $op->_post(
"/oauth2/userinfo",

Loading…
Cancel
Save