Merge branch 'refresh' into 'v2.0'
Add OIDC offline sessions and refresh tokens See merge request lemonldap-ng/lemonldap-ng!100
This commit is contained in:
commit
5b2e6f7d9f
@ -24,7 +24,7 @@ use constant MANAGERSECTION => "manager";
|
|||||||
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
|
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
|
||||||
use constant APPLYSECTION => "apply";
|
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 $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(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent|RequirePKCE|Public)|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|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' );
|
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
||||||
|
|
||||||
|
@ -166,14 +166,17 @@ sub defaultValues {
|
|||||||
'notificationStorageOptions' => {
|
'notificationStorageOptions' => {
|
||||||
'dirName' => '/var/lib/lemonldap-ng/notifications'
|
'dirName' => '/var/lib/lemonldap-ng/notifications'
|
||||||
},
|
},
|
||||||
'notificationWildcard' => 'allusers',
|
'notificationWildcard' => 'allusers',
|
||||||
'notifyDeleted' => 1,
|
'notifyDeleted' => 1,
|
||||||
'nullAuthnLevel' => 0,
|
'nullAuthnLevel' => 0,
|
||||||
'oidcAuthnLevel' => 1,
|
'oidcAuthnLevel' => 1,
|
||||||
'oidcRPCallbackGetParam' => 'openidconnectcallback',
|
'oidcRPCallbackGetParam' => 'openidconnectcallback',
|
||||||
'oidcRPStateTimeout' => 600,
|
'oidcRPStateTimeout' => 600,
|
||||||
'oidcServiceAllowAuthorizationCodeFlow' => 1,
|
'oidcServiceAccessTokenExpiration' => 3600,
|
||||||
'oidcServiceMetaDataAuthnContext' => {
|
'oidcServiceAllowAuthorizationCodeFlow' => 1,
|
||||||
|
'oidcServiceAuthorizationCodeExpiration' => 60,
|
||||||
|
'oidcServiceIDTokenExpiration' => 3600,
|
||||||
|
'oidcServiceMetaDataAuthnContext' => {
|
||||||
'loa-1' => 1,
|
'loa-1' => 1,
|
||||||
'loa-2' => 2,
|
'loa-2' => 2,
|
||||||
'loa-3' => 3,
|
'loa-3' => 3,
|
||||||
@ -190,6 +193,7 @@ sub defaultValues {
|
|||||||
'oidcServiceMetaDataRegistrationURI' => 'register',
|
'oidcServiceMetaDataRegistrationURI' => 'register',
|
||||||
'oidcServiceMetaDataTokenURI' => 'token',
|
'oidcServiceMetaDataTokenURI' => 'token',
|
||||||
'oidcServiceMetaDataUserInfoURI' => 'userinfo',
|
'oidcServiceMetaDataUserInfoURI' => 'userinfo',
|
||||||
|
'oidcServiceOfflineSessionExpiration' => 2592000,
|
||||||
'openIdAuthnLevel' => 1,
|
'openIdAuthnLevel' => 1,
|
||||||
'openIdExportedVars' => {},
|
'openIdExportedVars' => {},
|
||||||
'openIdIDPList' => '0;',
|
'openIdIDPList' => '0;',
|
||||||
|
@ -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 $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:UserAttribut|Servic|Rul)e|ExportedVars)';
|
||||||
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|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 $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(?:I(?:DToken(?:Expiration|SignAlg)|con)|Logout(?:SessionRequired|Type|Url)|R(?:e(?:directUris|quirePKCE)|ule)|P(?:ostLogoutRedirectUris|ublic)|AccessTokenExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|ExportedVars)';
|
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 $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 $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 $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)';
|
our $virtualHostKeys = '(?:vhost(?:A(?:uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';
|
||||||
@ -68,6 +68,6 @@ our $issuerParameters = {
|
|||||||
issuerOptions => [qw(issuersTimeout)],
|
issuerOptions => [qw(issuersTimeout)],
|
||||||
};
|
};
|
||||||
our $samlServiceParameters = [qw(samlEntityID samlServicePrivateKeySig samlServicePrivateKeySigPwd samlServicePublicKeySig samlServicePrivateKeyEnc samlServicePrivateKeyEncPwd samlServicePublicKeyEnc samlServiceUseCertificateInResponse samlServiceSignatureMethod samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos samlOrganizationDisplayName samlOrganizationName samlOrganizationURL samlSPSSODescriptorAuthnRequestsSigned samlSPSSODescriptorWantAssertionsSigned samlSPSSODescriptorSingleLogoutServiceHTTPRedirect samlSPSSODescriptorSingleLogoutServiceHTTPPost samlSPSSODescriptorSingleLogoutServiceSOAP samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact samlSPSSODescriptorAssertionConsumerServiceHTTPPost samlSPSSODescriptorArtifactResolutionServiceArtifact samlIDPSSODescriptorWantAuthnRequestsSigned samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect samlIDPSSODescriptorSingleSignOnServiceHTTPPost samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect samlIDPSSODescriptorSingleLogoutServiceHTTPPost samlIDPSSODescriptorSingleLogoutServiceSOAP samlIDPSSODescriptorArtifactResolutionServiceArtifact samlAttributeAuthorityDescriptorAttributeServiceSOAP samlMetadataForceUTF8 samlStorage samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter samlDiscoveryProtocolActivation samlDiscoveryProtocolURL samlDiscoveryProtocolPolicy samlDiscoveryProtocolIsPassive samlOverrideIDPEntityID)];
|
our $samlServiceParameters = [qw(samlEntityID samlServicePrivateKeySig samlServicePrivateKeySigPwd samlServicePublicKeySig samlServicePrivateKeyEnc samlServicePrivateKeyEncPwd samlServicePublicKeyEnc samlServiceUseCertificateInResponse samlServiceSignatureMethod samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos samlOrganizationDisplayName samlOrganizationName samlOrganizationURL samlSPSSODescriptorAuthnRequestsSigned samlSPSSODescriptorWantAssertionsSigned samlSPSSODescriptorSingleLogoutServiceHTTPRedirect samlSPSSODescriptorSingleLogoutServiceHTTPPost samlSPSSODescriptorSingleLogoutServiceSOAP samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact samlSPSSODescriptorAssertionConsumerServiceHTTPPost samlSPSSODescriptorArtifactResolutionServiceArtifact samlIDPSSODescriptorWantAuthnRequestsSigned samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect samlIDPSSODescriptorSingleSignOnServiceHTTPPost samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect samlIDPSSODescriptorSingleLogoutServiceHTTPPost samlIDPSSODescriptorSingleLogoutServiceSOAP samlIDPSSODescriptorArtifactResolutionServiceArtifact samlAttributeAuthorityDescriptorAttributeServiceSOAP samlMetadataForceUTF8 samlStorage samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter samlDiscoveryProtocolActivation samlDiscoveryProtocolURL samlDiscoveryProtocolPolicy samlDiscoveryProtocolIsPassive samlOverrideIDPEntityID)];
|
||||||
our $oidcServiceParameters = [qw(oidcServiceMetaDataIssuer oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI oidcServiceMetaDataIntrospectionURI oidcServiceMetaDataEndSessionURI oidcServiceMetaDataCheckSessionURI oidcServiceMetaDataFrontChannelURI oidcServiceMetaDataBackChannelURI oidcServiceMetaDataAuthnContext oidcServicePrivateKeySig oidcServicePublicKeySig oidcServiceKeyIdSig oidcServiceAllowDynamicRegistration oidcServiceAllowAuthorizationCodeFlow oidcServiceAllowImplicitFlow oidcServiceAllowHybridFlow oidcStorage oidcStorageOptions)];
|
our $oidcServiceParameters = [qw(oidcServiceMetaDataIssuer oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI oidcServiceMetaDataIntrospectionURI oidcServiceMetaDataEndSessionURI oidcServiceMetaDataCheckSessionURI oidcServiceMetaDataFrontChannelURI oidcServiceMetaDataBackChannelURI oidcServiceMetaDataAuthnContext oidcServicePrivateKeySig oidcServicePublicKeySig oidcServiceKeyIdSig oidcServiceAllowDynamicRegistration oidcServiceAllowAuthorizationCodeFlow oidcServiceAllowImplicitFlow oidcServiceAllowHybridFlow oidcServiceAuthorizationCodeExpiration oidcServiceAccessTokenExpiration oidcServiceIDTokenExpiration oidcServiceOfflineSessionExpiration oidcStorage oidcStorageOptions)];
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -24,6 +24,13 @@ sub setTypes {
|
|||||||
( $type eq 'global' ? 'SSO' : ucfirst($type) );
|
( $type eq 'global' ? 'SSO' : ucfirst($type) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $offlinebackend = $self->{sessionTypes}->{oidc} ? 'oidc' : 'global';
|
||||||
|
$self->{sessionTypes}->{offline}->{module} =
|
||||||
|
$self->{sessionTypes}->{$offlinebackend}->{module};
|
||||||
|
$self->{sessionTypes}->{offline}->{options} =
|
||||||
|
$self->{sessionTypes}->{$offlinebackend}->{options};
|
||||||
|
$self->{sessionTypes}->{offline}->{kind} = "OIDCI";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub separator {
|
sub separator {
|
||||||
|
@ -4,6 +4,60 @@ use strict;
|
|||||||
|
|
||||||
our $VERSION = '2.0.4';
|
our $VERSION = '2.0.4';
|
||||||
|
|
||||||
|
sub retrieveSession {
|
||||||
|
my ( $class, $req, $id ) = @_;
|
||||||
|
my ($offlineId) = $id =~ /^O-(.*)/;
|
||||||
|
|
||||||
|
# Retrieve regular session if this is not an offline access token
|
||||||
|
unless ($offlineId) {
|
||||||
|
return $class->Lemonldap::NG::Handler::Main::retrieveSession( $req,
|
||||||
|
$id );
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. Get the session from cache or backend
|
||||||
|
my $session = $req->data->{session} = (
|
||||||
|
Lemonldap::NG::Common::Session->new( {
|
||||||
|
storageModule => $class->tsv->{oidcStorageModule},
|
||||||
|
storageModuleOptions => $class->tsv->{oidcStorageOptions},
|
||||||
|
cacheModule => $class->tsv->{sessionCacheModule},
|
||||||
|
cacheModuleOptions => $class->tsv->{sessionCacheOptions},
|
||||||
|
id => $offlineId,
|
||||||
|
kind => "OIDCI",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ( $session->error ) {
|
||||||
|
|
||||||
|
$class->data( $session->data );
|
||||||
|
$class->logger->debug("Get session $offlineId from Handler::Main::Run");
|
||||||
|
|
||||||
|
# Verify that session is valid
|
||||||
|
$class->logger->error(
|
||||||
|
"_utime is not defined. This should not happen. Check if it is well transmitted to handler"
|
||||||
|
) unless $session->data->{_utime};
|
||||||
|
|
||||||
|
my $ttl = $class->tsv->{timeout} - time + $session->data->{_utime};
|
||||||
|
$class->logger->debug( "Session TTL = " . $ttl );
|
||||||
|
|
||||||
|
if ( time - $session->data->{_utime} > $class->tsv->{timeout} ) {
|
||||||
|
$class->logger->info("Session $id expired");
|
||||||
|
|
||||||
|
# Clean cached data
|
||||||
|
$class->data( {} );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $session->data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$class->logger->info("Session $offlineId can't be retrieved");
|
||||||
|
$class->logger->info( $session->error );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub fetchId {
|
sub fetchId {
|
||||||
my ( $class, $req ) = @_;
|
my ( $class, $req ) = @_;
|
||||||
|
|
||||||
@ -21,10 +75,16 @@ sub fetchId {
|
|||||||
|
|
||||||
# Get access token session
|
# Get access token session
|
||||||
my $infos = $class->getOIDCInfos($access_token);
|
my $infos = $class->getOIDCInfos($access_token);
|
||||||
|
# If this token is tied to a regular session ID
|
||||||
if ( my $_session_id = $infos->{user_session_id} ) {
|
if ( my $_session_id = $infos->{user_session_id} ) {
|
||||||
$class->logger->debug( 'Get user session id ' . $_session_id );
|
$class->logger->debug( 'Get user session id ' . $_session_id );
|
||||||
return $_session_id;
|
return $_session_id;
|
||||||
}
|
}
|
||||||
|
# If this token is tied to an Offline session
|
||||||
|
if ( my $_session_id = $infos->{offline_session_id} ) {
|
||||||
|
$class->logger->debug( 'Get offline session id ' . $_session_id );
|
||||||
|
return "O-$_session_id";
|
||||||
|
}
|
||||||
|
|
||||||
return $class->Lemonldap::NG::Handler::Main::fetchId($req);
|
return $class->Lemonldap::NG::Handler::Main::fetchId($req);
|
||||||
}
|
}
|
||||||
@ -50,7 +110,8 @@ sub getOIDCInfos {
|
|||||||
unless ( $oidcSession->error ) {
|
unless ( $oidcSession->error ) {
|
||||||
$class->logger->debug("Get OIDC session $id");
|
$class->logger->debug("Get OIDC session $id");
|
||||||
|
|
||||||
$infos->{user_session_id} = $oidcSession->data->{user_session_id};
|
$infos->{user_session_id} = $oidcSession->data->{user_session_id};
|
||||||
|
$infos->{offline_session_id} = $oidcSession->data->{offline_session_id};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$class->logger->info("OIDC Session $id can't be retrieved");
|
$class->logger->info("OIDC Session $id can't be retrieved");
|
||||||
|
@ -1211,6 +1211,9 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'default' => 5,
|
'default' => 5,
|
||||||
'type' => 'int'
|
'type' => 'int'
|
||||||
},
|
},
|
||||||
|
'forceGlobalStorageIssuerOTT' => {
|
||||||
|
'type' => 'bool'
|
||||||
|
},
|
||||||
'forceGlobalStorageUpgradeOTT' => {
|
'forceGlobalStorageUpgradeOTT' => {
|
||||||
'type' => 'bool'
|
'type' => 'bool'
|
||||||
},
|
},
|
||||||
@ -1979,8 +1982,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'type' => 'subContainer'
|
'type' => 'subContainer'
|
||||||
},
|
},
|
||||||
'oidcRPMetaDataOptionsAccessTokenExpiration' => {
|
'oidcRPMetaDataOptionsAccessTokenExpiration' => {
|
||||||
'default' => 3600,
|
'type' => 'int'
|
||||||
'type' => 'int'
|
},
|
||||||
|
'oidcRPMetaDataOptionsAllowOffline' => {
|
||||||
|
'default' => 0,
|
||||||
|
'type' => 'bool'
|
||||||
|
},
|
||||||
|
'oidcRPMetaDataOptionsAuthorizationCodeExpiration' => {
|
||||||
|
'type' => 'int'
|
||||||
},
|
},
|
||||||
'oidcRPMetaDataOptionsBypassConsent' => {
|
'oidcRPMetaDataOptionsBypassConsent' => {
|
||||||
'default' => 0,
|
'default' => 0,
|
||||||
@ -2003,8 +2012,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
'oidcRPMetaDataOptionsIDTokenExpiration' => {
|
'oidcRPMetaDataOptionsIDTokenExpiration' => {
|
||||||
'default' => 3600,
|
'type' => 'int'
|
||||||
'type' => 'int'
|
|
||||||
},
|
},
|
||||||
'oidcRPMetaDataOptionsIDTokenSignAlg' => {
|
'oidcRPMetaDataOptionsIDTokenSignAlg' => {
|
||||||
'default' => 'HS512',
|
'default' => 'HS512',
|
||||||
@ -2059,6 +2067,9 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'oidcRPMetaDataOptionsLogoutUrl' => {
|
'oidcRPMetaDataOptionsLogoutUrl' => {
|
||||||
'type' => 'url'
|
'type' => 'url'
|
||||||
},
|
},
|
||||||
|
'oidcRPMetaDataOptionsOfflineSessionExpiration' => {
|
||||||
|
'type' => 'int'
|
||||||
|
},
|
||||||
'oidcRPMetaDataOptionsPostLogoutRedirectUris' => {
|
'oidcRPMetaDataOptionsPostLogoutRedirectUris' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
@ -2069,6 +2080,10 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'oidcRPMetaDataOptionsRedirectUris' => {
|
'oidcRPMetaDataOptionsRedirectUris' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'oidcRPMetaDataOptionsRefreshToken' => {
|
||||||
|
'default' => 0,
|
||||||
|
'type' => 'bool'
|
||||||
|
},
|
||||||
'oidcRPMetaDataOptionsRequirePKCE' => {
|
'oidcRPMetaDataOptionsRequirePKCE' => {
|
||||||
'default' => 0,
|
'default' => 0,
|
||||||
'type' => 'bool'
|
'type' => 'bool'
|
||||||
@ -2086,6 +2101,10 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'default' => 600,
|
'default' => 600,
|
||||||
'type' => 'int'
|
'type' => 'int'
|
||||||
},
|
},
|
||||||
|
'oidcServiceAccessTokenExpiration' => {
|
||||||
|
'default' => 3600,
|
||||||
|
'type' => 'int'
|
||||||
|
},
|
||||||
'oidcServiceAllowAuthorizationCodeFlow' => {
|
'oidcServiceAllowAuthorizationCodeFlow' => {
|
||||||
'default' => 1,
|
'default' => 1,
|
||||||
'type' => 'bool'
|
'type' => 'bool'
|
||||||
@ -2102,6 +2121,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'default' => 0,
|
'default' => 0,
|
||||||
'type' => 'bool'
|
'type' => 'bool'
|
||||||
},
|
},
|
||||||
|
'oidcServiceAuthorizationCodeExpiration' => {
|
||||||
|
'default' => 60,
|
||||||
|
'type' => 'int'
|
||||||
|
},
|
||||||
|
'oidcServiceIDTokenExpiration' => {
|
||||||
|
'default' => 3600,
|
||||||
|
'type' => 'int'
|
||||||
|
},
|
||||||
'oidcServiceKeyIdSig' => {
|
'oidcServiceKeyIdSig' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
@ -2159,6 +2186,10 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||||||
'default' => 'userinfo',
|
'default' => 'userinfo',
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'oidcServiceOfflineSessionExpiration' => {
|
||||||
|
'default' => 2592000,
|
||||||
|
'type' => 'int'
|
||||||
|
},
|
||||||
'oidcServicePrivateKeySig' => {
|
'oidcServicePrivateKeySig' => {
|
||||||
'type' => 'RSAPrivateKey'
|
'type' => 'RSAPrivateKey'
|
||||||
},
|
},
|
||||||
|
@ -3619,6 +3619,26 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||||||
default => 0,
|
default => 0,
|
||||||
documentation => 'OpenID Connect allow hybrid flow',
|
documentation => 'OpenID Connect allow hybrid flow',
|
||||||
},
|
},
|
||||||
|
oidcServiceAuthorizationCodeExpiration => {
|
||||||
|
type => 'int',
|
||||||
|
default => 60,
|
||||||
|
documentation => 'OpenID Connect global code TTL',
|
||||||
|
},
|
||||||
|
oidcServiceAccessTokenExpiration => {
|
||||||
|
type => 'int',
|
||||||
|
default => 3600,
|
||||||
|
documentation => 'OpenID Connect global access token TTL',
|
||||||
|
},
|
||||||
|
oidcServiceIDTokenExpiration => {
|
||||||
|
type => 'int',
|
||||||
|
default => 3600,
|
||||||
|
documentation => 'OpenID Connect global ID token TTL',
|
||||||
|
},
|
||||||
|
oidcServiceOfflineSessionExpiration => {
|
||||||
|
type => 'int',
|
||||||
|
default => 2592000,
|
||||||
|
documentation => 'OpenID Connect global offline session TTL',
|
||||||
|
},
|
||||||
oidcStorage => {
|
oidcStorage => {
|
||||||
type => 'PerlModule',
|
type => 'PerlModule',
|
||||||
documentation => 'Apache::Session module to store OIDC user data',
|
documentation => 'Apache::Session module to store OIDC user data',
|
||||||
@ -3719,11 +3739,11 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||||||
],
|
],
|
||||||
default => 'HS512',
|
default => 'HS512',
|
||||||
},
|
},
|
||||||
oidcRPMetaDataOptionsIDTokenExpiration =>
|
oidcRPMetaDataOptionsIDTokenExpiration => { type => 'int' },
|
||||||
{ type => 'int', default => 3600 },
|
oidcRPMetaDataOptionsAccessTokenExpiration => { type => 'int' },
|
||||||
oidcRPMetaDataOptionsAccessTokenExpiration =>
|
oidcRPMetaDataOptionsAuthorizationCodeExpiration => { type => 'int' },
|
||||||
{ type => 'int', default => 3600 },
|
oidcRPMetaDataOptionsOfflineSessionExpiration => { type => 'int' },
|
||||||
oidcRPMetaDataOptionsRedirectUris => { type => 'text', },
|
oidcRPMetaDataOptionsRedirectUris => { type => 'text', },
|
||||||
oidcRPMetaDataOptionsExtraClaims =>
|
oidcRPMetaDataOptionsExtraClaims =>
|
||||||
{ type => 'keyTextContainer', default => {} },
|
{ type => 'keyTextContainer', default => {} },
|
||||||
oidcRPMetaDataOptionsBypassConsent => {
|
oidcRPMetaDataOptionsBypassConsent => {
|
||||||
@ -3760,6 +3780,16 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||||||
default => 0,
|
default => 0,
|
||||||
documentation => 'Require PKCE',
|
documentation => 'Require PKCE',
|
||||||
},
|
},
|
||||||
|
oidcRPMetaDataOptionsAllowOffline => {
|
||||||
|
type => 'bool',
|
||||||
|
default => 0,
|
||||||
|
documentation => 'Allow offline access',
|
||||||
|
},
|
||||||
|
oidcRPMetaDataOptionsRefreshToken => {
|
||||||
|
type => 'bool',
|
||||||
|
default => 0,
|
||||||
|
documentation => 'Issue refresh tokens',
|
||||||
|
},
|
||||||
oidcRPMetaDataOptionsRule => {
|
oidcRPMetaDataOptionsRule => {
|
||||||
type => 'text',
|
type => 'text',
|
||||||
test => sub { return perlExpr(@_) },
|
test => sub { return perlExpr(@_) },
|
||||||
|
@ -204,6 +204,10 @@ sub cTrees {
|
|||||||
'oidcRPMetaDataOptionsIDTokenSignAlg',
|
'oidcRPMetaDataOptionsIDTokenSignAlg',
|
||||||
'oidcRPMetaDataOptionsIDTokenExpiration',
|
'oidcRPMetaDataOptionsIDTokenExpiration',
|
||||||
'oidcRPMetaDataOptionsAccessTokenExpiration',
|
'oidcRPMetaDataOptionsAccessTokenExpiration',
|
||||||
|
'oidcRPMetaDataOptionsAuthorizationCodeExpiration',
|
||||||
|
'oidcRPMetaDataOptionsAllowOffline',
|
||||||
|
'oidcRPMetaDataOptionsRefreshToken',
|
||||||
|
'oidcRPMetaDataOptionsOfflineSessionExpiration',
|
||||||
'oidcRPMetaDataOptionsRedirectUris',
|
'oidcRPMetaDataOptionsRedirectUris',
|
||||||
'oidcRPMetaDataOptionsBypassConsent',
|
'oidcRPMetaDataOptionsBypassConsent',
|
||||||
{
|
{
|
||||||
|
@ -1166,6 +1166,10 @@ sub tree {
|
|||||||
'oidcServiceAllowAuthorizationCodeFlow',
|
'oidcServiceAllowAuthorizationCodeFlow',
|
||||||
'oidcServiceAllowImplicitFlow',
|
'oidcServiceAllowImplicitFlow',
|
||||||
'oidcServiceAllowHybridFlow',
|
'oidcServiceAllowHybridFlow',
|
||||||
|
'oidcServiceAuthorizationCodeExpiration',
|
||||||
|
'oidcServiceAccessTokenExpiration',
|
||||||
|
'oidcServiceIDTokenExpiration',
|
||||||
|
'oidcServiceOfflineSessionExpiration',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -99,6 +99,7 @@ sub sessions {
|
|||||||
my $params = $req->parameters();
|
my $params = $req->parameters();
|
||||||
my $type = delete $params->{sessionType};
|
my $type = delete $params->{sessionType};
|
||||||
$type = $type eq 'global' ? 'SSO' : ucfirst($type);
|
$type = $type eq 'global' ? 'SSO' : ucfirst($type);
|
||||||
|
$type = $type eq 'Offline' ? 'OIDCI' : ucfirst($type);
|
||||||
|
|
||||||
my $res;
|
my $res;
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ llapp.controller 'SessionsExplorerCtrl', ['$scope', '$translator', '$location',
|
|||||||
sessionType = 'global'
|
sessionType = 'global'
|
||||||
if n == null
|
if n == null
|
||||||
$scope.type = '_whatToTrace'
|
$scope.type = '_whatToTrace'
|
||||||
else if n[1].match /^(persistent)$/
|
else if n[1].match /^(persistent|offline)$/
|
||||||
sessionType = RegExp.$1
|
sessionType = RegExp.$1
|
||||||
$scope.type = '_session_uid'
|
$scope.type = '_session_uid'
|
||||||
else
|
else
|
||||||
|
@ -473,19 +473,43 @@ function templates(tpl,key) {
|
|||||||
"type" : "select"
|
"type" : "select"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default" : 3600,
|
|
||||||
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsIDTokenExpiration",
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsIDTokenExpiration",
|
||||||
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsIDTokenExpiration",
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsIDTokenExpiration",
|
||||||
"title" : "oidcRPMetaDataOptionsIDTokenExpiration",
|
"title" : "oidcRPMetaDataOptionsIDTokenExpiration",
|
||||||
"type" : "int"
|
"type" : "int"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default" : 3600,
|
|
||||||
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAccessTokenExpiration",
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAccessTokenExpiration",
|
||||||
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAccessTokenExpiration",
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAccessTokenExpiration",
|
||||||
"title" : "oidcRPMetaDataOptionsAccessTokenExpiration",
|
"title" : "oidcRPMetaDataOptionsAccessTokenExpiration",
|
||||||
"type" : "int"
|
"type" : "int"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAuthorizationCodeExpiration",
|
||||||
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAuthorizationCodeExpiration",
|
||||||
|
"title" : "oidcRPMetaDataOptionsAuthorizationCodeExpiration",
|
||||||
|
"type" : "int"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default" : 0,
|
||||||
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAllowOffline",
|
||||||
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsAllowOffline",
|
||||||
|
"title" : "oidcRPMetaDataOptionsAllowOffline",
|
||||||
|
"type" : "bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default" : 0,
|
||||||
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRefreshToken",
|
||||||
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRefreshToken",
|
||||||
|
"title" : "oidcRPMetaDataOptionsRefreshToken",
|
||||||
|
"type" : "bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsOfflineSessionExpiration",
|
||||||
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsOfflineSessionExpiration",
|
||||||
|
"title" : "oidcRPMetaDataOptionsOfflineSessionExpiration",
|
||||||
|
"type" : "int"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRedirectUris",
|
"get" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRedirectUris",
|
||||||
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRedirectUris",
|
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsRedirectUris",
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -511,7 +511,7 @@
|
|||||||
sessionType = 'global';
|
sessionType = 'global';
|
||||||
if (n === null) {
|
if (n === null) {
|
||||||
$scope.type = '_whatToTrace';
|
$scope.type = '_whatToTrace';
|
||||||
} else if (n[1].match(/^(persistent)$/)) {
|
} else if (n[1].match(/^(persistent|offline)$/)) {
|
||||||
sessionType = RegExp.$1;
|
sessionType = RegExp.$1;
|
||||||
$scope.type = '_session_uid';
|
$scope.type = '_session_uid';
|
||||||
} else {
|
} else {
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"لا شيء في المعايير",
|
"nullParams":"لا شيء في المعايير",
|
||||||
"number":"رقم",
|
"number":"رقم",
|
||||||
"off":"إيقاف",
|
"off":"إيقاف",
|
||||||
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"قيمة قديمة",
|
"oldValue":"قيمة قديمة",
|
||||||
"on":"تنشيط",
|
"on":"تنشيط",
|
||||||
"oidcAuthnLevel":"مستوى إثبات الهوية",
|
"oidcAuthnLevel":"مستوى إثبات الهوية",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":" أوبين أيدي كونيكت بروفيدر",
|
"oidcOPMetaDataNode":" أوبين أيدي كونيكت بروفيدر",
|
||||||
"oidcOPMetaDataOptions":"الخيارات",
|
"oidcOPMetaDataOptions":"الخيارات",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"إثبات الهوية",
|
"oidcRPMetaDataOptionsAuthentication":"إثبات الهوية",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Allow offline access",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"توقيع",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"توقيع",
|
||||||
"oidcOPMetaDataOptionsClientID":"معرف العميل",
|
"oidcOPMetaDataOptionsClientID":"معرف العميل",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"سرالعميل",
|
"oidcOPMetaDataOptionsClientSecret":"سرالعميل",
|
||||||
@ -557,6 +559,7 @@
|
|||||||
"oidcRPMetaDataNode":"الأطراف المعتمد لي أوبين أيدي كونيكت",
|
"oidcRPMetaDataNode":"الأطراف المعتمد لي أوبين أيدي كونيكت",
|
||||||
"oidcRPMetaDataOptions":"الخيارات",
|
"oidcRPMetaDataOptions":"الخيارات",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"انتهاء صلاحية التوكن",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"انتهاء صلاحية التوكن",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"تخطى الموافقة ",
|
"oidcRPMetaDataOptionsBypassConsent":"تخطى الموافقة ",
|
||||||
"oidcRPMetaDataOptionsClientID":"معرف العميل",
|
"oidcRPMetaDataOptionsClientID":"معرف العميل",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"سرالعميل",
|
"oidcRPMetaDataOptionsClientSecret":"سرالعميل",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"شعار",
|
"oidcRPMetaDataOptionsIcon":"شعار",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":" انتهاء صلاحية تعريف التوكن",
|
"oidcRPMetaDataOptionsIDTokenExpiration":" انتهاء صلاحية تعريف التوكن",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"خوارزمية توقيع آي دي التوكن",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"خوارزمية توقيع آي دي التوكن",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"خاصّيّة المستخدم",
|
"oidcRPMetaDataOptionsUserIDAttr":"خاصّيّة المستخدم",
|
||||||
"oidcRPName":"اسم أوبين أيدي كونيكت RP",
|
"oidcRPName":"اسم أوبين أيدي كونيكت RP",
|
||||||
"oidcRPStateTimeout":"حالة مهلة الجلسة",
|
"oidcRPStateTimeout":"حالة مهلة الجلسة",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"توقيع على المفتاح الخاص",
|
"oidcServicePrivateKeySig":"توقيع على المفتاح الخاص",
|
||||||
"oidcServicePublicKeySig":"توقيع على المفتاح العمومي",
|
"oidcServicePublicKeySig":"توقيع على المفتاح العمومي",
|
||||||
"oidcServiceKeyIdSig":"توقيع على هوية المفتاح ",
|
"oidcServiceKeyIdSig":"توقيع على هوية المفتاح ",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
|
"oidcServiceAccessTokenExpiration":"ﺎﻨﺘﻫﺍﺀ ﺹﻼﺤﻳﺓ ﺎﻠﺗﻮﻜﻧ",
|
||||||
|
"oidcServiceIDTokenExpiration":" ﺎﻨﺘﻫﺍﺀ ﺹﻼﺤﻳﺓ ﺖﻋﺮﻴﻓ ﺎﻠﺗﻮﻜﻧ",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
|
||||||
"oidcStorage":"اسم وحدة الجلسات",
|
"oidcStorage":"اسم وحدة الجلسات",
|
||||||
"oidcStorageOptions":"خيارات وحدة الجلسات",
|
"oidcStorageOptions":"خيارات وحدة الجلسات",
|
||||||
"oidcOPMetaDataNodes":" أوبين أيدي كونيكت بروفيدر",
|
"oidcOPMetaDataNodes":" أوبين أيدي كونيكت بروفيدر",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"ترخيص كود التدفق",
|
"oidcServiceAllowAuthorizationCodeFlow":"ترخيص كود التدفق",
|
||||||
"oidcServiceAllowImplicitFlow":"التدفق الضمني",
|
"oidcServiceAllowImplicitFlow":"التدفق الضمني",
|
||||||
"oidcServiceAllowHybridFlow":"تدفق هجين",
|
"oidcServiceAllowHybridFlow":"تدفق هجين",
|
||||||
|
"oidcServiceAllowOffline":"Allow offline access",
|
||||||
"ok":"حسنا",
|
"ok":"حسنا",
|
||||||
"oldNotifFormat":"استخدام صيغة xml القديمة",
|
"oldNotifFormat":"استخدام صيغة xml القديمة",
|
||||||
"openIdAttr":"تسجيل الدخول في أوبين أيدي",
|
"openIdAttr":"تسجيل الدخول في أوبين أيدي",
|
||||||
@ -1066,4 +1076,4 @@
|
|||||||
"samlRelayStateTimeout":"تناوب حالة مهلة الجلسة ",
|
"samlRelayStateTimeout":"تناوب حالة مهلة الجلسة ",
|
||||||
"samlUseQueryStringSpecific":"استخدام أسلوب query_string المعين",
|
"samlUseQueryStringSpecific":"استخدام أسلوب query_string المعين",
|
||||||
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
||||||
}
|
}
|
||||||
|
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"Null parameters",
|
"nullParams":"Null parameters",
|
||||||
"number":"Number",
|
"number":"Number",
|
||||||
"off":"Off",
|
"off":"Off",
|
||||||
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Old value",
|
"oldValue":"Old value",
|
||||||
"on":"On",
|
"on":"On",
|
||||||
"oidcAuthnLevel":"Authentication level",
|
"oidcAuthnLevel":"Authentication level",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":"OpenID Connect Providers",
|
"oidcOPMetaDataNode":"OpenID Connect Providers",
|
||||||
"oidcOPMetaDataOptions":"Optionen",
|
"oidcOPMetaDataOptions":"Optionen",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"Authentication",
|
"oidcRPMetaDataOptionsAuthentication":"Authentication",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Allow offline access",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"Check JWT signature",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"Check JWT signature",
|
||||||
"oidcOPMetaDataOptionsClientID":"Client ID",
|
"oidcOPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"Client secret",
|
"oidcOPMetaDataOptionsClientSecret":"Client secret",
|
||||||
@ -556,7 +558,8 @@
|
|||||||
"oidcRPMetaDataExportedVars":"Exported attributes",
|
"oidcRPMetaDataExportedVars":"Exported attributes",
|
||||||
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
||||||
"oidcRPMetaDataOptions":"Options",
|
"oidcRPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"Access token expiration",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"Access Token expiration",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"Bypass consent",
|
"oidcRPMetaDataOptionsBypassConsent":"Bypass consent",
|
||||||
"oidcRPMetaDataOptionsClientID":"Client ID",
|
"oidcRPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"Client secret",
|
"oidcRPMetaDataOptionsClientSecret":"Client secret",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"Logo",
|
"oidcRPMetaDataOptionsIcon":"Logo",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
|
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",
|
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",
|
||||||
"oidcRPName":"OpenID Connect RP Name",
|
"oidcRPName":"OpenID Connect RP Name",
|
||||||
"oidcRPStateTimeout":"State session timeout",
|
"oidcRPStateTimeout":"State session timeout",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"Signing private key",
|
"oidcServicePrivateKeySig":"Signing private key",
|
||||||
"oidcServicePublicKeySig":"Signing public key",
|
"oidcServicePublicKeySig":"Signing public key",
|
||||||
"oidcServiceKeyIdSig":"Signing key ID",
|
"oidcServiceKeyIdSig":"Signing key ID",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
|
"oidcServiceAccessTokenExpiration":"Access Token expiration",
|
||||||
|
"oidcServiceIDTokenExpiration":"ID Token expiration",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
|
||||||
"oidcStorage":"Sessions module name",
|
"oidcStorage":"Sessions module name",
|
||||||
"oidcStorageOptions":"Sessions module options",
|
"oidcStorageOptions":"Sessions module options",
|
||||||
"oidcOPMetaDataNodes":"OpenID Connect Providers",
|
"oidcOPMetaDataNodes":"OpenID Connect Providers",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
||||||
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
||||||
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
||||||
|
"oidcServiceAllowOffline":"Allow offline access",
|
||||||
"ok":"OK",
|
"ok":"OK",
|
||||||
"oldNotifFormat":"Use old XML format",
|
"oldNotifFormat":"Use old XML format",
|
||||||
"openIdAttr":"OpenID login",
|
"openIdAttr":"OpenID login",
|
||||||
@ -1066,4 +1076,4 @@
|
|||||||
"samlRelayStateTimeout":"RelayState session timeout",
|
"samlRelayStateTimeout":"RelayState session timeout",
|
||||||
"samlUseQueryStringSpecific":"Use specific query_string method",
|
"samlUseQueryStringSpecific":"Use specific query_string method",
|
||||||
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
||||||
}
|
}
|
||||||
|
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"Null parameters",
|
"nullParams":"Null parameters",
|
||||||
"number":"Number",
|
"number":"Number",
|
||||||
"off":"Off",
|
"off":"Off",
|
||||||
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Old value",
|
"oldValue":"Old value",
|
||||||
"on":"On",
|
"on":"On",
|
||||||
"oidcAuthnLevel":"Authentication level",
|
"oidcAuthnLevel":"Authentication level",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":"OpenID Connect Providers",
|
"oidcOPMetaDataNode":"OpenID Connect Providers",
|
||||||
"oidcOPMetaDataOptions":"Options",
|
"oidcOPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"Authentication",
|
"oidcRPMetaDataOptionsAuthentication":"Authentication",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Allow offline access",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"Check JWT signature",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"Check JWT signature",
|
||||||
"oidcOPMetaDataOptionsClientID":"Client ID",
|
"oidcOPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"Client secret",
|
"oidcOPMetaDataOptionsClientSecret":"Client secret",
|
||||||
@ -556,7 +558,8 @@
|
|||||||
"oidcRPMetaDataExportedVars":"Exported attributes",
|
"oidcRPMetaDataExportedVars":"Exported attributes",
|
||||||
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
||||||
"oidcRPMetaDataOptions":"Options",
|
"oidcRPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"Access token expiration",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"Access Token expiration",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"Bypass consent",
|
"oidcRPMetaDataOptionsBypassConsent":"Bypass consent",
|
||||||
"oidcRPMetaDataOptionsClientID":"Client ID",
|
"oidcRPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"Client secret",
|
"oidcRPMetaDataOptionsClientSecret":"Client secret",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"Logo",
|
"oidcRPMetaDataOptionsIcon":"Logo",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
|
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",
|
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",
|
||||||
"oidcRPName":"OpenID Connect RP Name",
|
"oidcRPName":"OpenID Connect RP Name",
|
||||||
"oidcRPStateTimeout":"State session timeout",
|
"oidcRPStateTimeout":"State session timeout",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"Signing private key",
|
"oidcServicePrivateKeySig":"Signing private key",
|
||||||
"oidcServicePublicKeySig":"Signing public key",
|
"oidcServicePublicKeySig":"Signing public key",
|
||||||
"oidcServiceKeyIdSig":"Signing key ID",
|
"oidcServiceKeyIdSig":"Signing key ID",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
|
"oidcServiceAccessTokenExpiration":"Access Token expiration",
|
||||||
|
"oidcServiceIDTokenExpiration":"ID Token expiration",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
|
||||||
"oidcStorage":"Sessions module name",
|
"oidcStorage":"Sessions module name",
|
||||||
"oidcStorageOptions":"Sessions module options",
|
"oidcStorageOptions":"Sessions module options",
|
||||||
"oidcOPMetaDataNodes":"OpenID Connect Providers",
|
"oidcOPMetaDataNodes":"OpenID Connect Providers",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
||||||
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
||||||
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
||||||
|
"oidcServiceAllowOffline":"Allow offline access",
|
||||||
"ok":"OK",
|
"ok":"OK",
|
||||||
"oldNotifFormat":"Use old XML format",
|
"oldNotifFormat":"Use old XML format",
|
||||||
"openIdAttr":"OpenID login",
|
"openIdAttr":"OpenID login",
|
||||||
|
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"Paramètres Null",
|
"nullParams":"Paramètres Null",
|
||||||
"number":"Numéro",
|
"number":"Numéro",
|
||||||
"off":"Désactivé",
|
"off":"Désactivé",
|
||||||
|
"offlineSessions":"Sessions hors ligne",
|
||||||
"oldValue":"Ancienne valeur",
|
"oldValue":"Ancienne valeur",
|
||||||
"on":"Activé",
|
"on":"Activé",
|
||||||
"oidcAuthnLevel":"Niveau d'authentification",
|
"oidcAuthnLevel":"Niveau d'authentification",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":"Fournisseurs OpenID Connect",
|
"oidcOPMetaDataNode":"Fournisseurs OpenID Connect",
|
||||||
"oidcOPMetaDataOptions":"Options",
|
"oidcOPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"Authentification",
|
"oidcRPMetaDataOptionsAuthentication":"Authentification",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Autoriser l'accès hors ligne",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"Vérifier la signature des jetons",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"Vérifier la signature des jetons",
|
||||||
"oidcOPMetaDataOptionsClientID":"Identifiant",
|
"oidcOPMetaDataOptionsClientID":"Identifiant",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"Mot de passe",
|
"oidcOPMetaDataOptionsClientSecret":"Mot de passe",
|
||||||
@ -557,6 +559,7 @@
|
|||||||
"oidcRPMetaDataNode":"Clients OpenID Connect",
|
"oidcRPMetaDataNode":"Clients OpenID Connect",
|
||||||
"oidcRPMetaDataOptions":"Options",
|
"oidcRPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"Expiration des jetons d'accès",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"Expiration des jetons d'accès",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Expiration des codes d'autorisation",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"Contourner le consentement",
|
"oidcRPMetaDataOptionsBypassConsent":"Contourner le consentement",
|
||||||
"oidcRPMetaDataOptionsClientID":"Identifiant",
|
"oidcRPMetaDataOptionsClientID":"Identifiant",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"Mot de passe",
|
"oidcRPMetaDataOptionsClientSecret":"Mot de passe",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"Logo",
|
"oidcRPMetaDataOptionsIcon":"Logo",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":"Expiration des jetons d'identité",
|
"oidcRPMetaDataOptionsIDTokenExpiration":"Expiration des jetons d'identité",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"Algorithme de signature des jetons d'identité",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"Algorithme de signature des jetons d'identité",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Expiration des sessions hors-ligne",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Utiliser les refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"Attribut de l'utilisateur",
|
"oidcRPMetaDataOptionsUserIDAttr":"Attribut de l'utilisateur",
|
||||||
"oidcRPName":"Nom du client OpenID Connect",
|
"oidcRPName":"Nom du client OpenID Connect",
|
||||||
"oidcRPStateTimeout":"Durée d'une session state",
|
"oidcRPStateTimeout":"Durée d'une session state",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"Clef privée de signature",
|
"oidcServicePrivateKeySig":"Clef privée de signature",
|
||||||
"oidcServicePublicKeySig":"Clef publique de signature",
|
"oidcServicePublicKeySig":"Clef publique de signature",
|
||||||
"oidcServiceKeyIdSig":"Identifiant de clef de signature",
|
"oidcServiceKeyIdSig":"Identifiant de clef de signature",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Expiration des codes d'autorisation",
|
||||||
|
"oidcServiceAccessTokenExpiration":"Expiration des jetons d'accès",
|
||||||
|
"oidcServiceIDTokenExpiration":"Expiration des jetons d'identité",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Expiration des sessions hors-ligne",
|
||||||
"oidcStorage":"Nom du module des sessions",
|
"oidcStorage":"Nom du module des sessions",
|
||||||
"oidcStorageOptions":"Options du module des sessions",
|
"oidcStorageOptions":"Options du module des sessions",
|
||||||
"oidcOPMetaDataNodes":"Fournisseurs OpenID Connect",
|
"oidcOPMetaDataNodes":"Fournisseurs OpenID Connect",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
||||||
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
||||||
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
||||||
|
"oidcServiceAllowOffline":"Autoriser l'accès hors ligne",
|
||||||
"ok":"OK",
|
"ok":"OK",
|
||||||
"oldNotifFormat":"Utiliser l'ancien format XML",
|
"oldNotifFormat":"Utiliser l'ancien format XML",
|
||||||
"openIdAttr":"Identifiant OpenID",
|
"openIdAttr":"Identifiant OpenID",
|
||||||
|
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"Parametri Null",
|
"nullParams":"Parametri Null",
|
||||||
"number":"Numero",
|
"number":"Numero",
|
||||||
"off":"Off",
|
"off":"Off",
|
||||||
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Vecchio valore",
|
"oldValue":"Vecchio valore",
|
||||||
"on":"On",
|
"on":"On",
|
||||||
"oidcAuthnLevel":"Livello di autenticazione",
|
"oidcAuthnLevel":"Livello di autenticazione",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":"Provider di OpenID Connect",
|
"oidcOPMetaDataNode":"Provider di OpenID Connect",
|
||||||
"oidcOPMetaDataOptions":"Opzioni",
|
"oidcOPMetaDataOptions":"Opzioni",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"Autenticazione",
|
"oidcRPMetaDataOptionsAuthentication":"Autenticazione",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Allow offline access",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"Controllare la firma JWT",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"Controllare la firma JWT",
|
||||||
"oidcOPMetaDataOptionsClientID":"ID Client",
|
"oidcOPMetaDataOptionsClientID":"ID Client",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"Segreto Client",
|
"oidcOPMetaDataOptionsClientSecret":"Segreto Client",
|
||||||
@ -557,6 +559,7 @@
|
|||||||
"oidcRPMetaDataNode":"Parti basate su OpenID Connect",
|
"oidcRPMetaDataNode":"Parti basate su OpenID Connect",
|
||||||
"oidcRPMetaDataOptions":"Opzioni",
|
"oidcRPMetaDataOptions":"Opzioni",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"Scadenza accesso token",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"Scadenza accesso token",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Scadenza Authorization Code",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"Consenso di bypass",
|
"oidcRPMetaDataOptionsBypassConsent":"Consenso di bypass",
|
||||||
"oidcRPMetaDataOptionsClientID":"ID Client",
|
"oidcRPMetaDataOptionsClientID":"ID Client",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"Segreto Client",
|
"oidcRPMetaDataOptionsClientSecret":"Segreto Client",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"Logo",
|
"oidcRPMetaDataOptionsIcon":"Logo",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":"Scadenza ID Token",
|
"oidcRPMetaDataOptionsIDTokenExpiration":"Scadenza ID Token",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"Algoritmo di firma di identificazione di Token",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"Algoritmo di firma di identificazione di Token",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Scadenza Refresh Token",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"Attributo utente",
|
"oidcRPMetaDataOptionsUserIDAttr":"Attributo utente",
|
||||||
"oidcRPName":"Nome di OpenID Connect RP",
|
"oidcRPName":"Nome di OpenID Connect RP",
|
||||||
"oidcRPStateTimeout":"Durata della sessione stato",
|
"oidcRPStateTimeout":"Durata della sessione stato",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"Firma della chiave privata",
|
"oidcServicePrivateKeySig":"Firma della chiave privata",
|
||||||
"oidcServicePublicKeySig":"Firma della chiave pubblica",
|
"oidcServicePublicKeySig":"Firma della chiave pubblica",
|
||||||
"oidcServiceKeyIdSig":"ID del codice di accesso",
|
"oidcServiceKeyIdSig":"ID del codice di accesso",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Scadenza Authorization Code",
|
||||||
|
"oidcServiceAccessTokenExpiration":"Scadenza accesso token",
|
||||||
|
"oidcServiceIDTokenExpiration":"Scadenza ID Token",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Scadenza Refresh Token",
|
||||||
"oidcStorage":"Nome del modulo Sessioni",
|
"oidcStorage":"Nome del modulo Sessioni",
|
||||||
"oidcStorageOptions":"Opzioni del modulo Sessioni",
|
"oidcStorageOptions":"Opzioni del modulo Sessioni",
|
||||||
"oidcOPMetaDataNodes":"Provider di OpenID Connect",
|
"oidcOPMetaDataNodes":"Provider di OpenID Connect",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"Flusso del codice di autorizzazione",
|
"oidcServiceAllowAuthorizationCodeFlow":"Flusso del codice di autorizzazione",
|
||||||
"oidcServiceAllowImplicitFlow":"Flusso implicito",
|
"oidcServiceAllowImplicitFlow":"Flusso implicito",
|
||||||
"oidcServiceAllowHybridFlow":"Flusso ibrido",
|
"oidcServiceAllowHybridFlow":"Flusso ibrido",
|
||||||
|
"oidcServiceAllowOffline":"Allow offline access",
|
||||||
"ok":"OK",
|
"ok":"OK",
|
||||||
"oldNotifFormat":"Utilizza il vecchio formato XML",
|
"oldNotifFormat":"Utilizza il vecchio formato XML",
|
||||||
"openIdAttr":"Login OpenID",
|
"openIdAttr":"Login OpenID",
|
||||||
@ -1066,4 +1076,4 @@
|
|||||||
"samlRelayStateTimeout":"Timeout di sessione di RelayState",
|
"samlRelayStateTimeout":"Timeout di sessione di RelayState",
|
||||||
"samlUseQueryStringSpecific":"Utilizza il metodo specifico query_string",
|
"samlUseQueryStringSpecific":"Utilizza il metodo specifico query_string",
|
||||||
"samlOverrideIDPEntityID":"Sostituisci l'ID entità quando agisce come IDP"
|
"samlOverrideIDPEntityID":"Sostituisci l'ID entità quando agisce come IDP"
|
||||||
}
|
}
|
||||||
|
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"Tham số Null",
|
"nullParams":"Tham số Null",
|
||||||
"number":"Số",
|
"number":"Số",
|
||||||
"off":"Tắt",
|
"off":"Tắt",
|
||||||
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Giá trị cũ",
|
"oldValue":"Giá trị cũ",
|
||||||
"on":"Vào",
|
"on":"Vào",
|
||||||
"oidcAuthnLevel":"Mức xác thực",
|
"oidcAuthnLevel":"Mức xác thực",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":"Nhà cung cấp Kết nối OpenID",
|
"oidcOPMetaDataNode":"Nhà cung cấp Kết nối OpenID",
|
||||||
"oidcOPMetaDataOptions":"Tùy chọn",
|
"oidcOPMetaDataOptions":"Tùy chọn",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"Xác thực",
|
"oidcRPMetaDataOptionsAuthentication":"Xác thực",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Allow offline access",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"Kiểm tra chữ ký JWT",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"Kiểm tra chữ ký JWT",
|
||||||
"oidcOPMetaDataOptionsClientID":"Client ID",
|
"oidcOPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"Trình khách bí mật",
|
"oidcOPMetaDataOptionsClientSecret":"Trình khách bí mật",
|
||||||
@ -557,6 +559,7 @@
|
|||||||
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
||||||
"oidcRPMetaDataOptions":"Tùy chọn",
|
"oidcRPMetaDataOptions":"Tùy chọn",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"Hết hạn truy cập Token",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"Hết hạn truy cập Token",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Authorization Code hết hạn",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"Bỏ qua sự đồng ý",
|
"oidcRPMetaDataOptionsBypassConsent":"Bỏ qua sự đồng ý",
|
||||||
"oidcRPMetaDataOptionsClientID":"Client ID",
|
"oidcRPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"Trình khách bí mật",
|
"oidcRPMetaDataOptionsClientSecret":"Trình khách bí mật",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"Logo",
|
"oidcRPMetaDataOptionsIcon":"Logo",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token hết hạn",
|
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token hết hạn",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"Thuật toán chữ ký ID Token",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"Thuật toán chữ ký ID Token",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Refresh Token hết hạn",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"thuộc tính người dùng",
|
"oidcRPMetaDataOptionsUserIDAttr":"thuộc tính người dùng",
|
||||||
"oidcRPName":"OpenID Connect RP Name",
|
"oidcRPName":"OpenID Connect RP Name",
|
||||||
"oidcRPStateTimeout":"Thời gian chờ của trạng thái phiên làm việc",
|
"oidcRPStateTimeout":"Thời gian chờ của trạng thái phiên làm việc",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"Ký khóa cá nhân",
|
"oidcServicePrivateKeySig":"Ký khóa cá nhân",
|
||||||
"oidcServicePublicKeySig":"Ký khóa công khai",
|
"oidcServicePublicKeySig":"Ký khóa công khai",
|
||||||
"oidcServiceKeyIdSig":"Khóa ID chính",
|
"oidcServiceKeyIdSig":"Khóa ID chính",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Authorization Code hết hạn",
|
||||||
|
"oidcServiceAccessTokenExpiration":"Hết hạn truy cập Token",
|
||||||
|
"oidcServiceIDTokenExpiration":"ID Token hết hạn",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Refresh Token hết hạn",
|
||||||
"oidcStorage":"Tên mô-đun phiên",
|
"oidcStorage":"Tên mô-đun phiên",
|
||||||
"oidcStorageOptions":"Tùy chọn mô-đun phiên",
|
"oidcStorageOptions":"Tùy chọn mô-đun phiên",
|
||||||
"oidcOPMetaDataNodes":"Nhà cung cấp Kết nối OpenID",
|
"oidcOPMetaDataNodes":"Nhà cung cấp Kết nối OpenID",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"Dòng mã ủy quyền",
|
"oidcServiceAllowAuthorizationCodeFlow":"Dòng mã ủy quyền",
|
||||||
"oidcServiceAllowImplicitFlow":"Dòng chảy ngầm",
|
"oidcServiceAllowImplicitFlow":"Dòng chảy ngầm",
|
||||||
"oidcServiceAllowHybridFlow":"Dòng chảy hỗn hợp",
|
"oidcServiceAllowHybridFlow":"Dòng chảy hỗn hợp",
|
||||||
|
"oidcServiceAllowOffline":"Allow offline access",
|
||||||
"ok":"OK",
|
"ok":"OK",
|
||||||
"oldNotifFormat":"Sử dụng định dạng XML cũ",
|
"oldNotifFormat":"Sử dụng định dạng XML cũ",
|
||||||
"openIdAttr":"Đăng nhập OpenID",
|
"openIdAttr":"Đăng nhập OpenID",
|
||||||
@ -1066,4 +1076,4 @@
|
|||||||
"samlRelayStateTimeout":"Thời gian hết hạn phiên RelayState ",
|
"samlRelayStateTimeout":"Thời gian hết hạn phiên RelayState ",
|
||||||
"samlUseQueryStringSpecific":"Sử dụng phương pháp query_string cụ thể",
|
"samlUseQueryStringSpecific":"Sử dụng phương pháp query_string cụ thể",
|
||||||
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
||||||
}
|
}
|
||||||
|
@ -517,6 +517,7 @@
|
|||||||
"nullParams":"Null parameters",
|
"nullParams":"Null parameters",
|
||||||
"number":"Number",
|
"number":"Number",
|
||||||
"off":"Off",
|
"off":"Off",
|
||||||
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Old value",
|
"oldValue":"Old value",
|
||||||
"on":"On",
|
"on":"On",
|
||||||
"oidcAuthnLevel":"认证等级",
|
"oidcAuthnLevel":"认证等级",
|
||||||
@ -528,6 +529,7 @@
|
|||||||
"oidcOPMetaDataNode":"OpenID Connect Providers",
|
"oidcOPMetaDataNode":"OpenID Connect Providers",
|
||||||
"oidcOPMetaDataOptions":"Options",
|
"oidcOPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAuthentication":"Authentication",
|
"oidcRPMetaDataOptionsAuthentication":"Authentication",
|
||||||
|
"oidcRPMetaDataOptionsAllowOffline":"Allow offline access",
|
||||||
"oidcOPMetaDataOptionsCheckJWTSignature":"Check JWT signature",
|
"oidcOPMetaDataOptionsCheckJWTSignature":"Check JWT signature",
|
||||||
"oidcOPMetaDataOptionsClientID":"Client ID",
|
"oidcOPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcOPMetaDataOptionsClientSecret":"Client secret",
|
"oidcOPMetaDataOptionsClientSecret":"Client secret",
|
||||||
@ -556,7 +558,8 @@
|
|||||||
"oidcRPMetaDataExportedVars":"Exported attributes",
|
"oidcRPMetaDataExportedVars":"Exported attributes",
|
||||||
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
||||||
"oidcRPMetaDataOptions":"Options",
|
"oidcRPMetaDataOptions":"Options",
|
||||||
"oidcRPMetaDataOptionsAccessTokenExpiration":"Access token expiration",
|
"oidcRPMetaDataOptionsAccessTokenExpiration":"Access Token expiration",
|
||||||
|
"oidcRPMetaDataOptionsAuthorizationCodeExpiration":"Authorization Code expiration",
|
||||||
"oidcRPMetaDataOptionsBypassConsent":"Bypass consent",
|
"oidcRPMetaDataOptionsBypassConsent":"Bypass consent",
|
||||||
"oidcRPMetaDataOptionsClientID":"Client ID",
|
"oidcRPMetaDataOptionsClientID":"Client ID",
|
||||||
"oidcRPMetaDataOptionsClientSecret":"Client secret",
|
"oidcRPMetaDataOptionsClientSecret":"Client secret",
|
||||||
@ -565,6 +568,8 @@
|
|||||||
"oidcRPMetaDataOptionsIcon":"Logo",
|
"oidcRPMetaDataOptionsIcon":"Logo",
|
||||||
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
|
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Token expiration",
|
||||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
|
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token signature algorithm",
|
||||||
|
"oidcRPMetaDataOptionsOfflineSessionExpiration":"Offline session expiration",
|
||||||
|
"oidcRPMetaDataOptionsRefreshToken":"Use refresh tokens",
|
||||||
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",
|
"oidcRPMetaDataOptionsUserIDAttr":"User attribute",
|
||||||
"oidcRPName":"OpenID Connect RP Name",
|
"oidcRPName":"OpenID Connect RP Name",
|
||||||
"oidcRPStateTimeout":"State session timeout",
|
"oidcRPStateTimeout":"State session timeout",
|
||||||
@ -584,6 +589,10 @@
|
|||||||
"oidcServicePrivateKeySig":"Signing private key",
|
"oidcServicePrivateKeySig":"Signing private key",
|
||||||
"oidcServicePublicKeySig":"Signing public key",
|
"oidcServicePublicKeySig":"Signing public key",
|
||||||
"oidcServiceKeyIdSig":"Signing key ID",
|
"oidcServiceKeyIdSig":"Signing key ID",
|
||||||
|
"oidcServiceAuthorizationCodeExpiration":"Authorization code expiration",
|
||||||
|
"oidcServiceAccessTokenExpiration":"Access Token expiration",
|
||||||
|
"oidcServiceIDTokenExpiration":"ID Token expiration",
|
||||||
|
"oidcServiceOfflineSessionExpiration":"Offline session expiration",
|
||||||
"oidcStorage":"Sessions module name",
|
"oidcStorage":"Sessions module name",
|
||||||
"oidcStorageOptions":"Sessions module options",
|
"oidcStorageOptions":"Sessions module options",
|
||||||
"oidcOPMetaDataNodes":"OpenID Connect Providers",
|
"oidcOPMetaDataNodes":"OpenID Connect Providers",
|
||||||
@ -605,6 +614,7 @@
|
|||||||
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
"oidcServiceAllowAuthorizationCodeFlow":"Authorization Code Flow",
|
||||||
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
"oidcServiceAllowImplicitFlow":"Implicit Flow",
|
||||||
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
"oidcServiceAllowHybridFlow":"Hybrid Flow",
|
||||||
|
"oidcServiceAllowOffline":"Allow offline access",
|
||||||
"ok":"OK",
|
"ok":"OK",
|
||||||
"oldNotifFormat":"Use old XML format",
|
"oldNotifFormat":"Use old XML format",
|
||||||
"openIdAttr":"OpenID login",
|
"openIdAttr":"OpenID login",
|
||||||
@ -1066,4 +1076,4 @@
|
|||||||
"samlRelayStateTimeout":"RelayState session timeout",
|
"samlRelayStateTimeout":"RelayState session timeout",
|
||||||
"samlUseQueryStringSpecific":"Use specific query_string method",
|
"samlUseQueryStringSpecific":"Use specific query_string method",
|
||||||
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -26,6 +26,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a id="a-persistent" href="#!/persistent" role="row"><i class="glyphicon glyphicon-lock"></i> {{translate('persistentSessions')}}</a></li>
|
<li><a id="a-persistent" href="#!/persistent" role="row"><i class="glyphicon glyphicon-lock"></i> {{translate('persistentSessions')}}</a></li>
|
||||||
|
<li><a id="a-offline" href="#!/offline" role="row"><i class="glyphicon glyphicon-time"></i> {{translate('offlineSessions')}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@ use Mouse;
|
|||||||
use Lemonldap::NG::Common::FormEncode;
|
use Lemonldap::NG::Common::FormEncode;
|
||||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||||
PE_BADURL
|
PE_BADURL
|
||||||
|
PE_BADCREDENTIALS
|
||||||
PE_CONFIRM
|
PE_CONFIRM
|
||||||
PE_ERROR
|
PE_ERROR
|
||||||
PE_LOGOUT_OK
|
PE_LOGOUT_OK
|
||||||
@ -547,11 +548,12 @@ sub run {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $scope_messages = {
|
my $scope_messages = {
|
||||||
openid => 'yourIdentity',
|
openid => 'yourIdentity',
|
||||||
profile => 'yourProfile',
|
profile => 'yourProfile',
|
||||||
email => 'yourEmail',
|
email => 'yourEmail',
|
||||||
address => 'yourAddress',
|
address => 'yourAddress',
|
||||||
phone => 'yourPhone',
|
phone => 'yourPhone',
|
||||||
|
offline_access => 'yourOffline',
|
||||||
};
|
};
|
||||||
my @list;
|
my @list;
|
||||||
foreach my $requested_scope (
|
foreach my $requested_scope (
|
||||||
@ -609,6 +611,47 @@ sub run {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# WIP: Offline access
|
||||||
|
my $offline = 0;
|
||||||
|
if ( $oidc_request->{'scope'} =~ /\boffline_access\b/ ) {
|
||||||
|
$offline = 1;
|
||||||
|
|
||||||
|
# MUST ensure that the prompt parameter contains consent unless
|
||||||
|
# other conditions for processing the request permitting offline
|
||||||
|
# access to the requested resources are in place; unless one or
|
||||||
|
# both of these conditions are fulfilled, then it MUST ignore
|
||||||
|
# the offline_access request,
|
||||||
|
unless ( $bypassConsent
|
||||||
|
or ( $prompt and $prompt =~ /\bconsent\b/ ) )
|
||||||
|
{
|
||||||
|
$self->logger->warn( "Offline access ignored, "
|
||||||
|
. "prompt parameter must contain \"consent\"" );
|
||||||
|
$offline = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# MUST ignore the offline_access request unless the Client is
|
||||||
|
# using a response_type value that would result in an
|
||||||
|
# Authorization Code being returned,
|
||||||
|
if ( $response_type !~ /\bcode\b/ ) {
|
||||||
|
$self->logger->warn( "Offline access incompatible "
|
||||||
|
. "with response type $response_type" );
|
||||||
|
$offline = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ignore offline_access request if not authorized by the RP
|
||||||
|
unless ( $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsAllowOffline} )
|
||||||
|
{
|
||||||
|
$self->logger->warn(
|
||||||
|
"Offline access not authorized for RP $rp");
|
||||||
|
$offline = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Strip offline_access from scopes from now on
|
||||||
|
$oidc_request->{'scope'} = join " ", grep !/^offline_access$/,
|
||||||
|
split /\s+/, $oidc_request->{'scope'};
|
||||||
|
}
|
||||||
|
|
||||||
# Authorization Code Flow
|
# Authorization Code Flow
|
||||||
if ( $flow eq "authorizationcode" ) {
|
if ( $flow eq "authorizationcode" ) {
|
||||||
|
|
||||||
@ -616,14 +659,15 @@ sub run {
|
|||||||
my $codeSession = $self->newAuthorizationCode(
|
my $codeSession = $self->newAuthorizationCode(
|
||||||
$rp,
|
$rp,
|
||||||
{
|
{
|
||||||
|
code_challenge => $oidc_request->{'code_challenge'},
|
||||||
|
code_challenge_method =>
|
||||||
|
$oidc_request->{'code_challenge_method'},
|
||||||
|
nonce => $oidc_request->{'nonce'},
|
||||||
|
offline => $offline,
|
||||||
redirect_uri => $oidc_request->{'redirect_uri'},
|
redirect_uri => $oidc_request->{'redirect_uri'},
|
||||||
scope => $oidc_request->{'scope'},
|
scope => $oidc_request->{'scope'},
|
||||||
client_id => $client_id,
|
client_id => $client_id,
|
||||||
user_session_id => $req->id,
|
user_session_id => $req->id,
|
||||||
nonce => $oidc_request->{'nonce'},
|
|
||||||
code_challenge => $oidc_request->{'code_challenge'},
|
|
||||||
code_challenge_method =>
|
|
||||||
$oidc_request->{'code_challenge_method'},
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -687,8 +731,10 @@ sub run {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ID token payload
|
# ID token payload
|
||||||
my $id_token_exp = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
my $id_token_exp =
|
||||||
->{oidcRPMetaDataOptionsIDTokenExpiration};
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsIDTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceIDTokenExpiration};
|
||||||
$id_token_exp += time;
|
$id_token_exp += time;
|
||||||
|
|
||||||
my $authenticationLevel =
|
my $authenticationLevel =
|
||||||
@ -733,7 +779,8 @@ sub run {
|
|||||||
# No access_token
|
# No access_token
|
||||||
# Claims must be set in id_token
|
# Claims must be set in id_token
|
||||||
my $claims =
|
my $claims =
|
||||||
$self->buildUserInfoResponse( $oidc_request->{'scope'},
|
$self->buildUserInfoResponseFromId(
|
||||||
|
$oidc_request->{'scope'},
|
||||||
$rp, $req->id );
|
$rp, $req->id );
|
||||||
|
|
||||||
foreach ( keys %$claims ) {
|
foreach ( keys %$claims ) {
|
||||||
@ -749,8 +796,10 @@ sub run {
|
|||||||
$self->logger->debug("Generated id token: $id_token");
|
$self->logger->debug("Generated id token: $id_token");
|
||||||
|
|
||||||
# Send token response
|
# Send token response
|
||||||
my $expires_in = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
my $expires_in =
|
||||||
->{oidcRPMetaDataOptionsAccessTokenExpiration};
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsAccessTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceAccessTokenExpiration};
|
||||||
|
|
||||||
# Build Response
|
# Build Response
|
||||||
my $response_url = $self->buildImplicitAuthnResponse(
|
my $response_url = $self->buildImplicitAuthnResponse(
|
||||||
@ -783,11 +832,12 @@ sub run {
|
|||||||
my $codeSession = $self->newAuthorizationCode(
|
my $codeSession = $self->newAuthorizationCode(
|
||||||
$rp,
|
$rp,
|
||||||
{
|
{
|
||||||
|
nonce => $oidc_request->{'nonce'},
|
||||||
|
offline => $offline,
|
||||||
redirect_uri => $oidc_request->{'redirect_uri'},
|
redirect_uri => $oidc_request->{'redirect_uri'},
|
||||||
client_id => $client_id,
|
client_id => $client_id,
|
||||||
scope => $oidc_request->{'scope'},
|
scope => $oidc_request->{'scope'},
|
||||||
user_session_id => $req->id,
|
user_session_id => $req->id,
|
||||||
nonce => $oidc_request->{'nonce'},
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -836,11 +886,13 @@ sub run {
|
|||||||
# ID token payload
|
# ID token payload
|
||||||
my $id_token_exp =
|
my $id_token_exp =
|
||||||
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
->{oidcRPMetaDataOptionsIDTokenExpiration};
|
->{oidcRPMetaDataOptionsIDTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceIDTokenExpiration};
|
||||||
$id_token_exp += time;
|
$id_token_exp += time;
|
||||||
|
|
||||||
my $id_token_acr =
|
my $id_token_acr =
|
||||||
"loa-" . $req->{sessionInfo}->{authenticationLevel};
|
"loa-"
|
||||||
|
. ( $req->{sessionInfo}->{authenticationLevel} || 0 );
|
||||||
|
|
||||||
my $user_id_attribute =
|
my $user_id_attribute =
|
||||||
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
@ -870,7 +922,7 @@ sub run {
|
|||||||
|
|
||||||
# No access_token
|
# No access_token
|
||||||
# Claims must be set in id_token
|
# Claims must be set in id_token
|
||||||
my $claims = $self->buildUserInfoResponse(
|
my $claims = $self->buildUserInfoResponseFromId(
|
||||||
$oidc_request->{'scope'},
|
$oidc_request->{'scope'},
|
||||||
$rp, $req->id );
|
$rp, $req->id );
|
||||||
|
|
||||||
@ -887,8 +939,10 @@ sub run {
|
|||||||
$self->logger->debug("Generated id token: $id_token");
|
$self->logger->debug("Generated id token: $id_token");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $expires_in = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
my $expires_in =
|
||||||
->{oidcRPMetaDataOptionsAccessTokenExpiration};
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsAccessTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceAccessTokenExpiration};
|
||||||
|
|
||||||
# Build Response
|
# Build Response
|
||||||
my $response_url = $self->buildHybridAuthnResponse(
|
my $response_url = $self->buildHybridAuthnResponse(
|
||||||
@ -1013,152 +1067,434 @@ sub token {
|
|||||||
|
|
||||||
my $client_id = $self->oidcRPList->{$rp}->{oidcRPMetaDataOptionsClientID};
|
my $client_id = $self->oidcRPList->{$rp}->{oidcRPMetaDataOptionsClientID};
|
||||||
|
|
||||||
# Get code session
|
my $grant_type = $req->param('grant_type');
|
||||||
my $code = $req->param('code');
|
|
||||||
|
|
||||||
unless ($code) {
|
# Autorization Code grant
|
||||||
$self->logger->error("No code found on token endpoint");
|
if ( $grant_type eq 'authorization_code' ) {
|
||||||
return $self->p->sendError( $req, 'invalid_request', 400 );
|
my $code = $req->param('code');
|
||||||
}
|
|
||||||
|
|
||||||
$self->logger->debug("OpenID Connect Code: $code");
|
unless ($code) {
|
||||||
|
$self->logger->error("No code found on token endpoint");
|
||||||
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
my $codeSession = $self->getAuthorizationCode($code);
|
my $codeSession = $self->getAuthorizationCode($code);
|
||||||
|
|
||||||
unless ($codeSession) {
|
unless ($codeSession) {
|
||||||
$self->logger->error("Unable to find OIDC session $code");
|
$self->logger->error("Unable to find OIDC session $code");
|
||||||
return $self->p->sendError( $req, 'invalid_request', 400 );
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check PKCE
|
$codeSession->remove();
|
||||||
if ( $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
|
||||||
->{oidcRPMetaDataOptionsRequirePKCE} )
|
# Check PKCE
|
||||||
{
|
if ( $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
unless (
|
->{oidcRPMetaDataOptionsRequirePKCE} )
|
||||||
$self->validatePKCEChallenge(
|
|
||||||
$req->param('code_verifier'),
|
|
||||||
$codeSession->data->{'code_challenge'},
|
|
||||||
$codeSession->data->{'code_challenge_method'}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
unless (
|
||||||
|
$self->validatePKCEChallenge(
|
||||||
|
$req->param('code_verifier'),
|
||||||
|
$codeSession->data->{'code_challenge'},
|
||||||
|
$codeSession->data->{'code_challenge_method'}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check we have the same client_id value
|
||||||
|
unless ( $client_id eq $codeSession->data->{client_id} ) {
|
||||||
|
$self->userLogger->error( "Provided client_id does not match "
|
||||||
|
. $codeSession->data->{client_id} );
|
||||||
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Check we have the same client_id value
|
# Check we have the same redirect_uri value
|
||||||
unless ( $client_id eq $codeSession->data->{client_id} ) {
|
unless (
|
||||||
$self->userLogger->error( "Provided client_id does not match "
|
$req->param("redirect_uri") eq $codeSession->data->{redirect_uri} )
|
||||||
. $codeSession->data->{client_id} );
|
|
||||||
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check we have the same redirect_uri value
|
|
||||||
unless ( $req->param("redirect_uri") eq $codeSession->data->{redirect_uri} )
|
|
||||||
{
|
|
||||||
$self->userLogger->error( "Provided redirect_uri does not match "
|
|
||||||
. $codeSession->data->{redirect_uri} );
|
|
||||||
return $self->p->sendError( $req, 'invalid_request', 400 );
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get user identifier
|
|
||||||
my $apacheSession =
|
|
||||||
$self->p->getApacheSession( $codeSession->data->{user_session_id},
|
|
||||||
noInfo => 1 );
|
|
||||||
|
|
||||||
unless ($apacheSession) {
|
|
||||||
$self->userLogger->error(
|
|
||||||
"Unable to find user session linked to OIDC session $code");
|
|
||||||
$codeSession->remove();
|
|
||||||
return $self->p->sendError( $req, 'invalid_request', 400 );
|
|
||||||
}
|
|
||||||
|
|
||||||
my $user_id_attribute =
|
|
||||||
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
|
||||||
->{oidcRPMetaDataOptionsUserIDAttr}
|
|
||||||
|| $self->conf->{whatToTrace};
|
|
||||||
my $user_id = $apacheSession->data->{$user_id_attribute};
|
|
||||||
|
|
||||||
$self->logger->debug("Found corresponding user: $user_id");
|
|
||||||
|
|
||||||
# Generate access_token
|
|
||||||
my $accessTokenSession = $self->newAccessToken(
|
|
||||||
$rp,
|
|
||||||
{
|
{
|
||||||
scope => $codeSession->data->{scope},
|
$self->userLogger->error( "Provided redirect_uri does not match "
|
||||||
rp => $rp,
|
. $codeSession->data->{redirect_uri} );
|
||||||
user_session_id => $apacheSession->id,
|
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
unless ($accessTokenSession) {
|
# Get user identifier
|
||||||
|
my $apacheSession =
|
||||||
|
$self->p->getApacheSession( $codeSession->data->{user_session_id},
|
||||||
|
noInfo => 1 );
|
||||||
|
|
||||||
|
unless ($apacheSession) {
|
||||||
|
$self->userLogger->error("Unable to find user session");
|
||||||
|
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
my $user_id_attribute =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsUserIDAttr}
|
||||||
|
|| $self->conf->{whatToTrace};
|
||||||
|
my $user_id = $apacheSession->data->{$user_id_attribute};
|
||||||
|
|
||||||
|
$self->logger->debug("Found corresponding user: $user_id");
|
||||||
|
|
||||||
|
# Generate access_token
|
||||||
|
my $accessTokenSession = $self->newAccessToken(
|
||||||
|
$rp,
|
||||||
|
{
|
||||||
|
scope => $codeSession->data->{scope},
|
||||||
|
rp => $rp,
|
||||||
|
user_session_id => $apacheSession->id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ($accessTokenSession) {
|
||||||
|
$self->userLogger->error(
|
||||||
|
"Unable to create OIDC session for access_token");
|
||||||
|
|
||||||
|
#FIXME: should be an error 500
|
||||||
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
my $access_token = $accessTokenSession->id;
|
||||||
|
|
||||||
|
$self->logger->debug("Generated access token: $access_token");
|
||||||
|
|
||||||
|
# Generate refresh_token
|
||||||
|
my $refresh_token = undef;
|
||||||
|
|
||||||
|
# For offline access, the refresh token isn't tied to the session ID
|
||||||
|
if ( $codeSession->{data}->{offline} ) {
|
||||||
|
|
||||||
|
# We need to remove _sessionType and _sessionid from the session data
|
||||||
|
# before storing session data in the refresh token
|
||||||
|
my %userInfo;
|
||||||
|
for
|
||||||
|
my $userKey ( grep !/^_session/, keys %{ $apacheSession->data } )
|
||||||
|
{
|
||||||
|
$userInfo{$userKey} = $apacheSession->data->{$userKey};
|
||||||
|
}
|
||||||
|
my $refreshTokenSession = $self->newRefreshToken(
|
||||||
|
$rp,
|
||||||
|
{
|
||||||
|
%userInfo,
|
||||||
|
redirect_uri => $codeSession->data->{redirect_uri},
|
||||||
|
scope => $codeSession->data->{scope},
|
||||||
|
client_id => $client_id,
|
||||||
|
_session_uid => $apacheSession->data->{_user},
|
||||||
|
auth_time => $apacheSession->data->{_lastAuthnUTime},
|
||||||
|
},
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ($refreshTokenSession) {
|
||||||
|
$self->userLogger->error(
|
||||||
|
"Unable to create OIDC session for refresh_token");
|
||||||
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$refresh_token = $refreshTokenSession->id;
|
||||||
|
|
||||||
|
$self->logger->debug("Generated refresh token: $refresh_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
# For online access, if configured
|
||||||
|
elsif ( $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsRefreshToken} )
|
||||||
|
{
|
||||||
|
my $refreshTokenSession = $self->newRefreshToken(
|
||||||
|
$rp,
|
||||||
|
{
|
||||||
|
redirect_uri => $codeSession->data->{redirect_uri},
|
||||||
|
scope => $codeSession->data->{scope},
|
||||||
|
client_id => $client_id,
|
||||||
|
user_session_id => $codeSession->data->{user_session_id},
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ($refreshTokenSession) {
|
||||||
|
$self->userLogger->error(
|
||||||
|
"Unable to create OIDC session for refresh_token");
|
||||||
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$refresh_token = $refreshTokenSession->id;
|
||||||
|
|
||||||
|
$self->logger->debug("Generated refresh token: $refresh_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compute hash to store in at_hash
|
||||||
|
my $alg = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsIDTokenSignAlg};
|
||||||
|
my ($hash_level) = ( $alg =~ /(?:\w{2})(\d{3})/ );
|
||||||
|
my $at_hash = $self->createHash( $access_token, $hash_level )
|
||||||
|
if $hash_level;
|
||||||
|
|
||||||
|
# ID token payload
|
||||||
|
my $id_token_exp =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsIDTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceIDTokenExpiration};
|
||||||
|
$id_token_exp += time;
|
||||||
|
|
||||||
|
my $id_token_acr = "loa-" . $apacheSession->data->{authenticationLevel};
|
||||||
|
|
||||||
|
my $id_token_payload_hash = {
|
||||||
|
iss => $self->conf->{oidcServiceMetaDataIssuer}, # Issuer Identifier
|
||||||
|
sub => $user_id, # Subject Identifier
|
||||||
|
aud => [$client_id], # Audience
|
||||||
|
exp => $id_token_exp, # expiration
|
||||||
|
iat => time, # Issued time
|
||||||
|
auth_time => $apacheSession->data->{_lastAuthnUTime}
|
||||||
|
, # Authentication time
|
||||||
|
acr => $id_token_acr, # Authentication Context Class Reference
|
||||||
|
azp => $client_id, # Authorized party
|
||||||
|
# TODO amr
|
||||||
|
};
|
||||||
|
|
||||||
|
my $nonce = $codeSession->data->{nonce};
|
||||||
|
$id_token_payload_hash->{nonce} = $nonce if defined $nonce;
|
||||||
|
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
|
||||||
|
|
||||||
|
# Create ID Token
|
||||||
|
my $id_token = $self->createIDToken( $id_token_payload_hash, $rp );
|
||||||
|
|
||||||
|
$self->logger->debug("Generated id token: $id_token");
|
||||||
|
|
||||||
|
# Send token response
|
||||||
|
my $expires_in =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsAccessTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceAccessTokenExpiration};
|
||||||
|
|
||||||
|
my $token_response = {
|
||||||
|
access_token => $access_token,
|
||||||
|
token_type => 'Bearer',
|
||||||
|
expires_in => $expires_in,
|
||||||
|
id_token => $id_token,
|
||||||
|
( $refresh_token ? ( refresh_token => $refresh_token ) : () ),
|
||||||
|
};
|
||||||
|
|
||||||
|
my $cRP = $apacheSession->data->{_oidcConnectedRP} || '';
|
||||||
|
unless ( $cRP =~ /\b$rp\b/ ) {
|
||||||
|
$self->p->updateSession( $req, { _oidcConnectedRP => "$rp,$cRP" },
|
||||||
|
$apacheSession->id );
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->logger->debug("Send token response");
|
||||||
|
|
||||||
|
return $self->p->sendJSONresponse( $req, $token_response );
|
||||||
|
}
|
||||||
|
|
||||||
|
# Refresh token
|
||||||
|
elsif ( $grant_type eq 'refresh_token' ) {
|
||||||
|
my $refresh_token = $req->param('refresh_token');
|
||||||
|
|
||||||
|
unless ($refresh_token) {
|
||||||
|
$self->logger->error("Missing refresh_token parameter");
|
||||||
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->logger->debug("OpenID Refresh Token: $refresh_token");
|
||||||
|
|
||||||
|
my $refreshSession = $self->getRefreshToken($refresh_token);
|
||||||
|
|
||||||
|
unless ($refreshSession) {
|
||||||
|
$self->logger->error("Unable to find OIDC session $refresh_token");
|
||||||
|
return $self->p->sendError( $req, 'invalid_request', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check we have the same client_id value
|
||||||
|
unless ( $client_id eq $refreshSession->data->{client_id} ) {
|
||||||
|
$self->userLogger->error( "Provided client_id does not match "
|
||||||
|
. $refreshSession->data->{client_id} );
|
||||||
|
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
my $access_token;
|
||||||
|
my $user_id;
|
||||||
|
my $auth_time;
|
||||||
|
|
||||||
|
# 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);
|
||||||
|
|
||||||
|
unless ($session) {
|
||||||
|
$self->logger->error("Unable to find user session");
|
||||||
|
return $self->returnBearerError( 'invalid_request',
|
||||||
|
'Invalid request', 401 );
|
||||||
|
}
|
||||||
|
|
||||||
|
my $user_id_attribute =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsUserIDAttr}
|
||||||
|
|| $self->conf->{whatToTrace};
|
||||||
|
$user_id = $session->data->{$user_id_attribute};
|
||||||
|
|
||||||
|
$auth_time = $session->data->{_lastAuthnUTime};
|
||||||
|
|
||||||
|
# Generate access_token
|
||||||
|
my $accessTokenSession = $self->newAccessToken(
|
||||||
|
$rp,
|
||||||
|
{
|
||||||
|
scope => $refreshSession->data->{scope},
|
||||||
|
rp => $rp,
|
||||||
|
user_session_id => $user_session_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ($accessTokenSession) {
|
||||||
|
$self->userLogger->error(
|
||||||
|
"Unable to create OIDC session for access_token");
|
||||||
|
return $self->p->sendError( $req,
|
||||||
|
'Unable to create Access Token', 500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$access_token = $accessTokenSession->id;
|
||||||
|
|
||||||
|
$self->logger->debug("Generated access token: $access_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Else, we are in an offline session
|
||||||
|
else {
|
||||||
|
|
||||||
|
# Lookup attributes and macros for user
|
||||||
|
$req->user( $refreshSession->data->{_session_uid} );
|
||||||
|
$req->steps( [
|
||||||
|
'getUser', @{ $self->p->betweenAuthAndData },
|
||||||
|
'setSessionInfo', 'setMacros',
|
||||||
|
'setGroups', 'setLocalGroups',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$req->{error} = $self->p->process($req);
|
||||||
|
|
||||||
|
if ( $req->error > 0 ) {
|
||||||
|
|
||||||
|
# PE_BADCREDENTIAL is returned by UserDB modules when the user was
|
||||||
|
# explicitely not found. And not in case of temporary failures
|
||||||
|
if ( $req->error == PE_BADCREDENTIALS ) {
|
||||||
|
$self->logger->error( "User: "
|
||||||
|
. $req->user
|
||||||
|
. " no longer exists, removing offline session" );
|
||||||
|
$refreshSession->remove;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->logger->error(
|
||||||
|
"Could not resolve user: " . $req->user );
|
||||||
|
}
|
||||||
|
return $self->p->sendError( $req, 'invalid_grant', 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update refresh session
|
||||||
|
$self->updateRefreshToken( $refreshSession->id, $req->sessionInfo );
|
||||||
|
|
||||||
|
my $user_id_attribute =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsUserIDAttr}
|
||||||
|
|| $self->conf->{whatToTrace};
|
||||||
|
$user_id = $req->sessionInfo->{$user_id_attribute};
|
||||||
|
$self->logger->debug("Found corresponding user: $user_id");
|
||||||
|
|
||||||
|
$auth_time = $refreshSession->data->{auth_time};
|
||||||
|
|
||||||
|
# Generate access_token
|
||||||
|
my $accessTokenSession = $self->newAccessToken(
|
||||||
|
$rp,
|
||||||
|
{
|
||||||
|
scope => $refreshSession->data->{scope},
|
||||||
|
rp => $rp,
|
||||||
|
offline_session_id => $refreshSession->id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ($accessTokenSession) {
|
||||||
|
$self->userLogger->error(
|
||||||
|
"Unable to create OIDC session for access_token");
|
||||||
|
return $self->p->sendError( $req,
|
||||||
|
'Unable to create Access Token', 500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$access_token = $accessTokenSession->id;
|
||||||
|
|
||||||
|
$self->logger->debug("Generated access token: $access_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compute hash to store in at_hash
|
||||||
|
my $alg = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsIDTokenSignAlg};
|
||||||
|
my ($hash_level) = ( $alg =~ /(?:\w{2})(\d{3})/ );
|
||||||
|
my $at_hash = $self->createHash( $access_token, $hash_level )
|
||||||
|
if $hash_level;
|
||||||
|
|
||||||
|
# ID token payload
|
||||||
|
my $id_token_exp =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsIDTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceIDTokenExpiration};
|
||||||
|
$id_token_exp += time;
|
||||||
|
|
||||||
|
# Authentication level using refresh tokens should probably stay at 0
|
||||||
|
my $id_token_acr = "loa-0";
|
||||||
|
|
||||||
|
my $id_token_payload_hash = {
|
||||||
|
iss => $self->conf->{oidcServiceMetaDataIssuer}, # Issuer Identifier
|
||||||
|
sub => $user_id, # Subject Identifier
|
||||||
|
aud => [$client_id], # Audience
|
||||||
|
exp => $id_token_exp, # expiration
|
||||||
|
iat => time, # Issued time
|
||||||
|
# TODO: is this the right value when using refresh tokens??
|
||||||
|
auth_time => $auth_time, # Authentication time
|
||||||
|
acr => $id_token_acr, # Authentication Context Class Reference
|
||||||
|
azp => $client_id, # Authorized party
|
||||||
|
# TODO amr
|
||||||
|
};
|
||||||
|
|
||||||
|
my $nonce = $refreshSession->data->{nonce};
|
||||||
|
$id_token_payload_hash->{nonce} = $nonce if defined $nonce;
|
||||||
|
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
|
||||||
|
|
||||||
|
# Create ID Token
|
||||||
|
my $id_token = $self->createIDToken( $id_token_payload_hash, $rp );
|
||||||
|
|
||||||
|
$self->logger->debug("Generated id token: $id_token");
|
||||||
|
|
||||||
|
# Send token response
|
||||||
|
my $expires_in =
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsAccessTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceAccessTokenExpiration};
|
||||||
|
|
||||||
|
my $token_response = {
|
||||||
|
access_token => $access_token,
|
||||||
|
token_type => 'Bearer',
|
||||||
|
expires_in => $expires_in,
|
||||||
|
id_token => $id_token,
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
#my $cRP = $apacheSession->data->{_oidcConnectedRP} || '';
|
||||||
|
#unless ( $cRP =~ /\b$rp\b/ ) {
|
||||||
|
# $self->p->updateSession( $req, { _oidcConnectedRP => "$rp,$cRP" },
|
||||||
|
# $apacheSession->id );
|
||||||
|
#}
|
||||||
|
|
||||||
|
$self->logger->debug("Send token response");
|
||||||
|
|
||||||
|
return $self->p->sendJSONresponse( $req, $token_response );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unknown or unspecified grant type
|
||||||
|
else {
|
||||||
$self->userLogger->error(
|
$self->userLogger->error(
|
||||||
"Unable to create OIDC session for access_token");
|
$grant_type
|
||||||
$codeSession->remove();
|
? "Missing grant_type parameter"
|
||||||
return $self->p->sendError( $req, 'invalid_request', 400 );
|
: "Unknown grant type: $grant_type"
|
||||||
|
);
|
||||||
|
return $self->p->sendError( $req, 'unsupported_grant_type', 400 );
|
||||||
}
|
}
|
||||||
|
|
||||||
my $access_token = $accessTokenSession->id;
|
|
||||||
|
|
||||||
$self->logger->debug("Generated access token: $access_token");
|
|
||||||
|
|
||||||
# Compute hash to store in at_hash
|
|
||||||
my $alg = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
|
||||||
->{oidcRPMetaDataOptionsIDTokenSignAlg};
|
|
||||||
my ($hash_level) = ( $alg =~ /(?:\w{2})(\d{3})/ );
|
|
||||||
my $at_hash = $self->createHash( $access_token, $hash_level )
|
|
||||||
if $hash_level;
|
|
||||||
|
|
||||||
# ID token payload
|
|
||||||
my $id_token_exp = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
|
||||||
->{oidcRPMetaDataOptionsIDTokenExpiration};
|
|
||||||
$id_token_exp += time;
|
|
||||||
|
|
||||||
my $id_token_acr = "loa-" . $apacheSession->data->{authenticationLevel};
|
|
||||||
|
|
||||||
my $id_token_payload_hash = {
|
|
||||||
iss => $self->iss,
|
|
||||||
sub => $user_id, # Subject Identifier
|
|
||||||
aud => [$client_id], # Audience
|
|
||||||
exp => $id_token_exp, # expiration
|
|
||||||
iat => time, # Issued time
|
|
||||||
auth_time => $apacheSession->data->{_lastAuthnUTime}
|
|
||||||
, # Authentication time
|
|
||||||
acr => $id_token_acr, # Authentication Context Class Reference
|
|
||||||
azp => $client_id, # Authorized party
|
|
||||||
# TODO amr
|
|
||||||
};
|
|
||||||
|
|
||||||
my $nonce = $codeSession->data->{nonce};
|
|
||||||
$id_token_payload_hash->{nonce} = $nonce if defined $nonce;
|
|
||||||
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
|
|
||||||
|
|
||||||
# Create ID Token
|
|
||||||
my $id_token = $self->createIDToken( $id_token_payload_hash, $rp );
|
|
||||||
|
|
||||||
$self->logger->debug("Generated id token: $id_token");
|
|
||||||
|
|
||||||
# Send token response
|
|
||||||
my $expires_in = $self->conf->{oidcRPMetaDataOptions}->{$rp}
|
|
||||||
->{oidcRPMetaDataOptionsAccessTokenExpiration};
|
|
||||||
|
|
||||||
my $token_response = {
|
|
||||||
access_token => $access_token,
|
|
||||||
token_type => 'Bearer',
|
|
||||||
expires_in => $expires_in,
|
|
||||||
id_token => $id_token,
|
|
||||||
};
|
|
||||||
|
|
||||||
my $cRP = $apacheSession->data->{_oidcConnectedRP} || '';
|
|
||||||
unless ( $cRP =~ /\b$rp\b/ ) {
|
|
||||||
$self->p->updateSession( $req, { _oidcConnectedRP => "$rp,$cRP" },
|
|
||||||
$apacheSession->id );
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->logger->debug("Send token response");
|
|
||||||
|
|
||||||
$codeSession->remove();
|
|
||||||
return $self->p->sendJSONresponse( $req, $token_response );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Handle userinfo endpoint
|
# Handle userinfo endpoint
|
||||||
@ -1190,8 +1526,39 @@ sub userInfo {
|
|||||||
my $rp = $accessTokenSession->data->{rp};
|
my $rp = $accessTokenSession->data->{rp};
|
||||||
my $user_session_id = $accessTokenSession->data->{user_session_id};
|
my $user_session_id = $accessTokenSession->data->{user_session_id};
|
||||||
|
|
||||||
|
my $session;
|
||||||
|
|
||||||
|
# If using a refreshed access token
|
||||||
|
if ($user_session_id) {
|
||||||
|
|
||||||
|
# Get user identifier
|
||||||
|
$session = $self->p->getApacheSession($user_session_id);
|
||||||
|
|
||||||
|
unless ($session) {
|
||||||
|
$self->logger->error("Unable to find user session");
|
||||||
|
return $self->returnBearerError( 'invalid_request',
|
||||||
|
'Invalid request', 401 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my $offline_session_id =
|
||||||
|
$accessTokenSession->data->{offline_session_id};
|
||||||
|
unless ($offline_session_id) {
|
||||||
|
return $self->returnBearerError( 'invalid_request',
|
||||||
|
'Invalid request', 401 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$session = $self->getRefreshToken($offline_session_id);
|
||||||
|
|
||||||
|
unless ($session) {
|
||||||
|
$self->logger->error("Unable to find refresh session");
|
||||||
|
return $self->returnBearerError( 'invalid_request',
|
||||||
|
'Invalid request', 401 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $userinfo_response =
|
my $userinfo_response =
|
||||||
$self->buildUserInfoResponse( $scope, $rp, $user_session_id );
|
$self->buildUserInfoResponse( $scope, $rp, $session );
|
||||||
unless ($userinfo_response) {
|
unless ($userinfo_response) {
|
||||||
return $self->returnBearerError( 'invalid_request', 'Invalid request',
|
return $self->returnBearerError( 'invalid_request', 'Invalid request',
|
||||||
401 );
|
401 );
|
||||||
|
@ -637,8 +637,15 @@ sub decodeJSON {
|
|||||||
sub newAuthorizationCode {
|
sub newAuthorizationCode {
|
||||||
my ( $self, $rp, $info ) = @_;
|
my ( $self, $rp, $info ) = @_;
|
||||||
|
|
||||||
return $self->getOpenIDConnectSession( undef, "authorization_code", undef,
|
return $self->getOpenIDConnectSession(
|
||||||
$info );
|
undef,
|
||||||
|
"authorization_code",
|
||||||
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
|
->{oidcRPMetaDataOptionsAuthorizationCodeExpiration}
|
||||||
|
|| $self->conf->{oidcServiceAuthorizationCodeExpiration},
|
||||||
|
,
|
||||||
|
$info
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get existing Authorization Code
|
# Get existing Authorization Code
|
||||||
@ -662,7 +669,8 @@ sub newAccessToken {
|
|||||||
undef,
|
undef,
|
||||||
"access_token",
|
"access_token",
|
||||||
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
->{oidcRPMetaDataOptionsAccessTokenExpiration},
|
->{oidcRPMetaDataOptionsAccessTokenExpiration}
|
||||||
|
|| $self->conf->{oidcServiceAccessTokenExpiration},
|
||||||
$info
|
$info
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -677,6 +685,68 @@ sub getAccessToken {
|
|||||||
return $self->getOpenIDConnectSession( $id, "access_token" );
|
return $self->getOpenIDConnectSession( $id, "access_token" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Create a new Refresh Token
|
||||||
|
# @param info hashref of session info
|
||||||
|
# @return new Lemonldap::NG::Common::Session object
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing Refresh Token
|
||||||
|
# @param id
|
||||||
|
# @return new Lemonldap::NG::Common::Session object
|
||||||
|
|
||||||
|
sub getRefreshToken {
|
||||||
|
my ( $self, $id ) = @_;
|
||||||
|
|
||||||
|
return $self->getOpenIDConnectSession( $id, "refresh_token" );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub updateRefreshToken {
|
||||||
|
my ( $self, $id, $infos ) = @_;
|
||||||
|
|
||||||
|
my %storage = (
|
||||||
|
storageModule => $self->conf->{oidcStorage},
|
||||||
|
storageModuleOptions => $self->conf->{oidcStorageOptions},
|
||||||
|
);
|
||||||
|
|
||||||
|
unless ( $storage{storageModule} ) {
|
||||||
|
%storage = (
|
||||||
|
storageModule => $self->conf->{globalStorage},
|
||||||
|
storageModuleOptions => $self->conf->{globalStorageOptions},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $oidcSession = Lemonldap::NG::Common::Session->new( {
|
||||||
|
%storage,
|
||||||
|
cacheModule => $self->conf->{localSessionStorage},
|
||||||
|
cacheModuleOptions => $self->conf->{localSessionStorageOptions},
|
||||||
|
id => $id,
|
||||||
|
info => $infos,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $oidcSession->error ) {
|
||||||
|
$self->userLogger->warn(
|
||||||
|
"OpenIDConnect session $id isn't yet available");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oidcSession;
|
||||||
|
}
|
||||||
|
|
||||||
# Try to recover the OpenID Connect session corresponding to id and return session
|
# Try to recover the OpenID Connect session corresponding to id and return session
|
||||||
# If id is set to undef, return a new session
|
# If id is set to undef, return a new session
|
||||||
# @return Lemonldap::NG::Common::Session object
|
# @return Lemonldap::NG::Common::Session object
|
||||||
@ -739,6 +809,15 @@ sub getOpenIDConnectSession {
|
|||||||
. $type );
|
. $type );
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Make sure the token is still valid, we already compensated for
|
||||||
|
# different TTLs when storing _utime
|
||||||
|
if (
|
||||||
|
time > ( $oidcSession->{data}->{_utime} + $self->conf->{timeout} ) )
|
||||||
|
{
|
||||||
|
$self->logger->error("Session $id has expired");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Make sure the token is still valid, we already compensated for
|
# Make sure the token is still valid, we already compensated for
|
||||||
@ -1221,22 +1300,28 @@ sub getAttributesListFromClaim {
|
|||||||
# @param rp Internal Relying Party identifier
|
# @param rp Internal Relying Party identifier
|
||||||
# @param user_session_id User session identifier
|
# @param user_session_id User session identifier
|
||||||
# @return hashref UserInfo data
|
# @return hashref UserInfo data
|
||||||
sub buildUserInfoResponse {
|
sub buildUserInfoResponseFromId {
|
||||||
my ( $self, $scope, $rp, $user_session_id ) = @_;
|
my ( $self, $scope, $rp, $user_session_id ) = @_;
|
||||||
|
my $session = $self->p->getApacheSession($user_session_id);
|
||||||
|
|
||||||
|
return undef unless ($session);
|
||||||
|
return buildUserInfoResponse( $self, $scope, $rp, $session );
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return Hash of UserInfo data
|
||||||
|
# @param scope OIDC scope
|
||||||
|
# @param rp Internal Relying Party identifier
|
||||||
|
# @param session SSO or offline session
|
||||||
|
# @return hashref UserInfo data
|
||||||
|
sub buildUserInfoResponse {
|
||||||
|
my ( $self, $scope, $rp, $session ) = @_;
|
||||||
my $userinfo_response = {};
|
my $userinfo_response = {};
|
||||||
|
|
||||||
# Get user identifier
|
|
||||||
my $apacheSession = $self->p->getApacheSession($user_session_id);
|
|
||||||
|
|
||||||
unless ($apacheSession) {
|
|
||||||
$self->logger->error("Unable to find user session");
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
my $user_id_attribute =
|
my $user_id_attribute =
|
||||||
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
$self->conf->{oidcRPMetaDataOptions}->{$rp}
|
||||||
->{oidcRPMetaDataOptionsUserIDAttr}
|
->{oidcRPMetaDataOptionsUserIDAttr}
|
||||||
|| $self->conf->{whatToTrace};
|
|| $self->conf->{whatToTrace};
|
||||||
my $user_id = $apacheSession->data->{$user_id_attribute};
|
my $user_id = $session->data->{$user_id_attribute};
|
||||||
|
|
||||||
$self->logger->debug("Found corresponding user: $user_id");
|
$self->logger->debug("Found corresponding user: $user_id");
|
||||||
|
|
||||||
@ -1252,7 +1337,7 @@ sub buildUserInfoResponse {
|
|||||||
my $session_key =
|
my $session_key =
|
||||||
$self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute};
|
$self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute};
|
||||||
if ($session_key) {
|
if ($session_key) {
|
||||||
my $session_value = $apacheSession->data->{$session_key};
|
my $session_value = $session->data->{$session_key};
|
||||||
|
|
||||||
# Address is a JSON object
|
# Address is a JSON object
|
||||||
if ( $claim eq "address" ) {
|
if ( $claim eq "address" ) {
|
||||||
@ -1665,6 +1750,10 @@ Generate new Authorization Code session
|
|||||||
|
|
||||||
Generate new Access Token session
|
Generate new Access Token session
|
||||||
|
|
||||||
|
=head2 newRefreshToken
|
||||||
|
|
||||||
|
Generate new Refresh Token session
|
||||||
|
|
||||||
=head2 getAuthorizationCode
|
=head2 getAuthorizationCode
|
||||||
|
|
||||||
Get existing Authorization Code session
|
Get existing Authorization Code session
|
||||||
@ -1673,6 +1762,10 @@ Get existing Authorization Code session
|
|||||||
|
|
||||||
Get existing Access Token session
|
Get existing Access Token session
|
||||||
|
|
||||||
|
=head2 getRefreshToken
|
||||||
|
|
||||||
|
Get existing Refresh Token session
|
||||||
|
|
||||||
=head2 getOpenIDConnectSession
|
=head2 getOpenIDConnectSession
|
||||||
|
|
||||||
Try to recover the OpenID Connect session corresponding to id and return session
|
Try to recover the OpenID Connect session corresponding to id and return session
|
||||||
@ -1717,9 +1810,13 @@ Get Access Token
|
|||||||
|
|
||||||
Return list of attributes authorized for a claim
|
Return list of attributes authorized for a claim
|
||||||
|
|
||||||
|
=head2 buildUserInfoResponseFromId
|
||||||
|
|
||||||
|
Return Hash of UserInfo data from session ID
|
||||||
|
|
||||||
=head2 buildUserInfoResponse
|
=head2 buildUserInfoResponse
|
||||||
|
|
||||||
Return Hash of UserInfo data
|
Return Hash of UserInfo data from session object
|
||||||
|
|
||||||
=head2 createJWT
|
=head2 createJWT
|
||||||
|
|
||||||
|
@ -273,8 +273,9 @@
|
|||||||
"yourKeyIsUnregistered":"تمت إزالة المفتاح",
|
"yourKeyIsUnregistered":"تمت إزالة المفتاح",
|
||||||
"yourKeyIsVerified":"تم اختبار المفتاح الخاص بك بنجاح",
|
"yourKeyIsVerified":"تم اختبار المفتاح الخاص بك بنجاح",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
|
"yourOffline": "and access your account while you are offline",
|
||||||
"yourPhone":"رقم هاتفك",
|
"yourPhone":"رقم هاتفك",
|
||||||
"yourProfile":"ملفك الشخصي",
|
"yourProfile":"ملفك الشخصي",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"Nicht gefunden: Du versuchst, auf eine nicht verfügbare Seite zuzugreifen",
|
"notFound":"Nicht gefunden: Du versuchst, auf eine nicht verfügbare Seite zuzugreifen",
|
||||||
"noTOTPFound":"Kein TOTP gefunden",
|
"noTOTPFound":"Kein TOTP gefunden",
|
||||||
"noU2FKeyFound":"Kein U2F Schlüssel gefunden",
|
"noU2FKeyFound":"Kein U2F Schlüssel gefunden",
|
||||||
"oidcConsent":"Die Anwendung %s möchte wissen:",
|
"oidcConsent":"Die Anwendung %s möchte:",
|
||||||
"oidcConsents":"OIDC consents",
|
"oidcConsents":"OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Warnung",
|
"warning":"Warnung",
|
||||||
"welcomeOnPortal":"Willkommen in Ihrem gesicherten Authentifizierungsportal.",
|
"welcomeOnPortal":"Willkommen in Ihrem gesicherten Authentifizierungsportal.",
|
||||||
"yesResendMail":"Ja, Mail erneut senden.",
|
"yesResendMail":"Ja, Mail erneut senden.",
|
||||||
"yourAddress":"Ihre Adresse",
|
"yourAddress":"Wissen Ihre Adresse",
|
||||||
"yourApps":"Ihre Applikationen",
|
"yourApps":"Ihre Applikationen",
|
||||||
"yourEmail":"Ihre Mailadresse",
|
"yourEmail":"Wissen Ihre Mailadresse",
|
||||||
"yourIdentity":"Ihre Identität",
|
"yourIdentity":"Wissen Ihre Identität",
|
||||||
"yourIdentityIs":"Ihre Identität ist",
|
"yourIdentityIs":"Ihre Identität ist",
|
||||||
"yourKeyIsRegistered":"Ihr Key wurde registriert",
|
"yourKeyIsRegistered":"Ihr Key wurde registriert",
|
||||||
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Ihr Key ist bestätigt",
|
"yourKeyIsVerified":"Ihr Key ist bestätigt",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
"yourPhone":"Ihre Telefonnummer",
|
"yourOffline": "and access your account while you are offline",
|
||||||
"yourProfile":"Ihr Profil",
|
"yourPhone":"Wissen Ihre Telefonnummer",
|
||||||
|
"yourProfile":"Wissen Ihr Profil",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound": "Not found: you try to access to an unavailable page",
|
"notFound": "Not found: you try to access to an unavailable page",
|
||||||
"noTOTPFound":"No TOTP found",
|
"noTOTPFound":"No TOTP found",
|
||||||
"noU2FKeyFound": "No U2F key found",
|
"noU2FKeyFound": "No U2F key found",
|
||||||
"oidcConsent":"The application %s would like to know:",
|
"oidcConsent":"The application %s would like to:",
|
||||||
"oidcConsents": "OIDC consents",
|
"oidcConsents": "OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Warning",
|
"warning":"Warning",
|
||||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||||
"yesResendMail":"Yes, resend the mail",
|
"yesResendMail":"Yes, resend the mail",
|
||||||
"yourAddress":"Your address",
|
"yourAddress":"Know your address",
|
||||||
"yourApps":"Your applications",
|
"yourApps":"Your applications",
|
||||||
"yourEmail":"Your email",
|
"yourEmail":"Know your email",
|
||||||
"yourIdentity":"Your identity",
|
"yourIdentity":"Know your identity",
|
||||||
"yourIdentityIs":"Your identity is",
|
"yourIdentityIs":"Your identity is",
|
||||||
"yourKeyIsRegistered":"Your key is registered",
|
"yourKeyIsRegistered":"Your key is registered",
|
||||||
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Your key is verified",
|
"yourKeyIsVerified":"Your key is verified",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
"yourPhone":"Your phone number",
|
"yourOffline": "Access your account while you are offline",
|
||||||
"yourProfile":"Your profile",
|
"yourPhone":"Know your phone number",
|
||||||
|
"yourProfile":"Know your profile",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -273,8 +273,9 @@
|
|||||||
"yourKeyIsUnregistered":"Su llave ha sido suprimida",
|
"yourKeyIsUnregistered":"Su llave ha sido suprimida",
|
||||||
"yourKeyIsVerified":"Su llave está verificada",
|
"yourKeyIsVerified":"Su llave está verificada",
|
||||||
"yourNewTotpKey":"Su nueva llave TOTP, por favor pruébela e ingrese el código",
|
"yourNewTotpKey":"Su nueva llave TOTP, por favor pruébela e ingrese el código",
|
||||||
|
"yourOffline": "Access your account while you are offline",
|
||||||
"yourPhone":"Su número telefónico",
|
"yourPhone":"Su número telefónico",
|
||||||
"yourProfile":"Su perfil",
|
"yourProfile":"Su perfil",
|
||||||
"yourTotpKey":"Su llave TOTP",
|
"yourTotpKey":"Su llave TOTP",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"Not found: you try to access to an unavailable page",
|
"notFound":"Not found: you try to access to an unavailable page",
|
||||||
"noTOTPFound":"No TOTP found",
|
"noTOTPFound":"No TOTP found",
|
||||||
"noU2FKeyFound":"No U2F key found",
|
"noU2FKeyFound":"No U2F key found",
|
||||||
"oidcConsent":"The application %s would like to know:",
|
"oidcConsent":"The application %s would like to:",
|
||||||
"oidcConsents":"OIDC consents",
|
"oidcConsents":"OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -273,8 +273,9 @@
|
|||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Your key is verified",
|
"yourKeyIsVerified":"Your key is verified",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
|
"yourOffline": "and access your account while you are offline",
|
||||||
"yourPhone":"Puhelinnumerosi",
|
"yourPhone":"Puhelinnumerosi",
|
||||||
"yourProfile":"Profiilisi",
|
"yourProfile":"Profiilisi",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound": "Non trouvé : vous tentez d'accéder à une page non disponible",
|
"notFound": "Non trouvé : vous tentez d'accéder à une page non disponible",
|
||||||
"noTOTPFound":"Aucun secret TOTP trouvé",
|
"noTOTPFound":"Aucun secret TOTP trouvé",
|
||||||
"noU2FKeyFound": "Aucune clef U2F trouvée",
|
"noU2FKeyFound": "Aucune clef U2F trouvée",
|
||||||
"oidcConsent":"L'application %s voudrait connaître :",
|
"oidcConsent":"L'application %s voudrait :",
|
||||||
"oidcConsents": "Accords OIDC",
|
"oidcConsents": "Accords OIDC",
|
||||||
"oidcConsentsFull":"Accords OpenID Connect",
|
"oidcConsentsFull":"Accords OpenID Connect",
|
||||||
"oneExpired2Fremoved":"Un second facteur expiré a été supprimé !",
|
"oneExpired2Fremoved":"Un second facteur expiré a été supprimé !",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Attention",
|
"warning":"Attention",
|
||||||
"welcomeOnPortal":"Bienvenue sur votre portail d'authentification sécurisée.",
|
"welcomeOnPortal":"Bienvenue sur votre portail d'authentification sécurisée.",
|
||||||
"yesResendMail":"Oui, renvoyer le mail",
|
"yesResendMail":"Oui, renvoyer le mail",
|
||||||
"yourAddress":"Votre adresse",
|
"yourAddress":"Connaître votre adresse",
|
||||||
"yourApps":"Vos applications",
|
"yourApps":"Vos applications",
|
||||||
"yourEmail":"Votre adresse électronique",
|
"yourEmail":"Connaître votre adresse électronique",
|
||||||
"yourIdentity":"Votre identité",
|
"yourIdentity":"Connaître votre identité",
|
||||||
"yourIdentityIs":"Votre identité est",
|
"yourIdentityIs":"Votre identité est",
|
||||||
"yourKeyIsRegistered":"Votre clef est enregistrée",
|
"yourKeyIsRegistered":"Votre clef est enregistrée",
|
||||||
"yourKeyIsAlreadyRegistered":"Votre clef est déjà enregistrée !",
|
"yourKeyIsAlreadyRegistered":"Votre clef est déjà enregistrée !",
|
||||||
"yourKeyIsUnregistered":"Votre clef a été supprimée",
|
"yourKeyIsUnregistered":"Votre clef a été supprimée",
|
||||||
"yourKeyIsVerified":"Votre clef est vérifiée",
|
"yourKeyIsVerified":"Votre clef est vérifiée",
|
||||||
"yourNewTotpKey":"Votre nouvelle clef TOTP. Testez-la et entrez le code",
|
"yourNewTotpKey":"Votre nouvelle clef TOTP. Testez-la et entrez le code",
|
||||||
"yourPhone":"Votre numéro de téléphone",
|
"yourOffline": "Accéder à votre compte lorsque vous êtes hors-ligne",
|
||||||
"yourProfile":"Vos informations personnelles",
|
"yourPhone":"Connaître votre numéro de téléphone",
|
||||||
|
"yourProfile":"Connaître vos informations personnelles",
|
||||||
"yourTotpKey":"Votre clef TOTP",
|
"yourTotpKey":"Votre clef TOTP",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"Non trovato: si tenta di accedere ad una pagina non disponibile",
|
"notFound":"Non trovato: si tenta di accedere ad una pagina non disponibile",
|
||||||
"noTOTPFound":"Nessun TOTP trovato",
|
"noTOTPFound":"Nessun TOTP trovato",
|
||||||
"noU2FKeyFound":"Nessuna chiave U2F trovata",
|
"noU2FKeyFound":"Nessuna chiave U2F trovata",
|
||||||
"oidcConsent":"L'applicazione %s vorrebbe sapere:",
|
"oidcConsent":"L'applicazione %s vorrebbe:",
|
||||||
"oidcConsents":"Consensi OIDC",
|
"oidcConsents":"Consensi OIDC",
|
||||||
"oidcConsentsFull":"Consensi OpenID Connect",
|
"oidcConsentsFull":"Consensi OpenID Connect",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Avvertimento",
|
"warning":"Avvertimento",
|
||||||
"welcomeOnPortal":"Benvenuto sul tuo portale di autenticazione protetta.",
|
"welcomeOnPortal":"Benvenuto sul tuo portale di autenticazione protetta.",
|
||||||
"yesResendMail":"Sì, rinvia e-mail",
|
"yesResendMail":"Sì, rinvia e-mail",
|
||||||
"yourAddress":"Il vostro indirizzo",
|
"yourAddress":"Sapere vostro indirizzo",
|
||||||
"yourApps":"Le vostre applicazioni",
|
"yourApps":"Le vostre applicazioni",
|
||||||
"yourEmail":"E-mail",
|
"yourEmail":"Sapere vostro E-mail",
|
||||||
"yourIdentity":"Identità",
|
"yourIdentity":"Sapere vostro Identità",
|
||||||
"yourIdentityIs":"La tua identità é",
|
"yourIdentityIs":"La tua identità é",
|
||||||
"yourKeyIsRegistered":"La vostra chiave è registrata",
|
"yourKeyIsRegistered":"La vostra chiave è registrata",
|
||||||
"yourKeyIsAlreadyRegistered":"La tua chiave è GIÀ registrata !",
|
"yourKeyIsAlreadyRegistered":"La tua chiave è GIÀ registrata !",
|
||||||
"yourKeyIsUnregistered":"La vostra chiave è stata rimossa",
|
"yourKeyIsUnregistered":"La vostra chiave è stata rimossa",
|
||||||
"yourKeyIsVerified":"La tua chiave é stata testata con successo",
|
"yourKeyIsVerified":"La tua chiave é stata testata con successo",
|
||||||
"yourNewTotpKey":"La tua nuova chiave TOTP, per favore provala e inserisci il codice",
|
"yourNewTotpKey":"La tua nuova chiave TOTP, per favore provala e inserisci il codice",
|
||||||
"yourPhone":"Numero di telefono",
|
"yourOffline": "and access your account while you are offline",
|
||||||
"yourProfile":"Il tuo profilo",
|
"yourPhone":"Sapere vostro numero di telefono",
|
||||||
|
"yourProfile":"Sapere vostro profilo",
|
||||||
"yourTotpKey":"La tua chiave TOTP",
|
"yourTotpKey":"La tua chiave TOTP",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"Not found: you try to access to an unavailable page",
|
"notFound":"Not found: you try to access to an unavailable page",
|
||||||
"noTOTPFound":"No TOTP found",
|
"noTOTPFound":"No TOTP found",
|
||||||
"noU2FKeyFound":"No U2F key found",
|
"noU2FKeyFound":"No U2F key found",
|
||||||
"oidcConsent":"The application %s would like to know:",
|
"oidcConsent":"The application %s would like to:",
|
||||||
"oidcConsents":"OIDC consents",
|
"oidcConsents":"OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Warning",
|
"warning":"Warning",
|
||||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||||
"yesResendMail":"Yes, resend the mail",
|
"yesResendMail":"Yes, resend the mail",
|
||||||
"yourAddress":"Your address",
|
"yourAddress":"Know your address",
|
||||||
"yourApps":"Your applications",
|
"yourApps":"Your applications",
|
||||||
"yourEmail":"Your email",
|
"yourEmail":"Know your email",
|
||||||
"yourIdentity":"Your identity",
|
"yourIdentity":"Know your identity",
|
||||||
"yourIdentityIs":"Your identity is",
|
"yourIdentityIs":"Your identity is",
|
||||||
"yourKeyIsRegistered":"Your key is registered",
|
"yourKeyIsRegistered":"Your key is registered",
|
||||||
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Your key is verified",
|
"yourKeyIsVerified":"Your key is verified",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
"yourPhone":"Your phone number",
|
"yourOffline": "Access your account while you are offline",
|
||||||
"yourProfile":"Your profile",
|
"yourPhone":"Know your phone number",
|
||||||
|
"yourProfile":"Know your profile",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"Not found: you try to access to an unavailable page",
|
"notFound":"Not found: you try to access to an unavailable page",
|
||||||
"noTOTPFound":"No TOTP found",
|
"noTOTPFound":"No TOTP found",
|
||||||
"noU2FKeyFound":"No U2F key found",
|
"noU2FKeyFound":"No U2F key found",
|
||||||
"oidcConsent":"The application %s would like to know:",
|
"oidcConsent":"The application %s would like to:",
|
||||||
"oidcConsents":"OIDC consents",
|
"oidcConsents":"OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Warning",
|
"warning":"Warning",
|
||||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||||
"yesResendMail":"Yes, resend the mail",
|
"yesResendMail":"Yes, resend the mail",
|
||||||
"yourAddress":"Your address",
|
"yourAddress":"Know your address",
|
||||||
"yourApps":"Your applications",
|
"yourApps":"Your applications",
|
||||||
"yourEmail":"Your email",
|
"yourEmail":"Know your email",
|
||||||
"yourIdentity":"Your identity",
|
"yourIdentity":"Know your identity",
|
||||||
"yourIdentityIs":"Your identity is",
|
"yourIdentityIs":"Your identity is",
|
||||||
"yourKeyIsRegistered":"Your key is registered",
|
"yourKeyIsRegistered":"Your key is registered",
|
||||||
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Your key is verified",
|
"yourKeyIsVerified":"Your key is verified",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
"yourPhone":"Your phone number",
|
"yourOffline": "Access your account while you are offline",
|
||||||
"yourProfile":"Your profile",
|
"yourPhone":"Know your phone number",
|
||||||
|
"yourProfile":"Know your profile",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"Not found: you try to access to an unavailable page",
|
"notFound":"Not found: you try to access to an unavailable page",
|
||||||
"noTOTPFound":"No TOTP found",
|
"noTOTPFound":"No TOTP found",
|
||||||
"noU2FKeyFound":"No U2F key found",
|
"noU2FKeyFound":"No U2F key found",
|
||||||
"oidcConsent":"The application %s would like to know:",
|
"oidcConsent":"The application %s would like to:",
|
||||||
"oidcConsents":"OIDC consents",
|
"oidcConsents":"OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -263,18 +263,19 @@
|
|||||||
"warning":"Warning",
|
"warning":"Warning",
|
||||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||||
"yesResendMail":"Yes, resend the mail",
|
"yesResendMail":"Yes, resend the mail",
|
||||||
"yourAddress":"Your address",
|
"yourAddress":"Know your address",
|
||||||
"yourApps":"Your applications",
|
"yourApps":"Your applications",
|
||||||
"yourEmail":"Your email",
|
"yourEmail":"Know your email",
|
||||||
"yourIdentity":"Your identity",
|
"yourIdentity":"Know your identity",
|
||||||
"yourIdentityIs":"Your identity is",
|
"yourIdentityIs":"Your identity is",
|
||||||
"yourKeyIsRegistered":"Your key is registered",
|
"yourKeyIsRegistered":"Your key is registered",
|
||||||
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
"yourKeyIsAlreadyRegistered":"Your key is ALREADY registered!",
|
||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Your key is verified",
|
"yourKeyIsVerified":"Your key is verified",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
"yourPhone":"Your phone number",
|
"yourOffline": "Access your account while you are offline",
|
||||||
"yourProfile":"Your profile",
|
"yourPhone":"Know your phone number",
|
||||||
|
"yourProfile":"Know your profile",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -273,8 +273,9 @@
|
|||||||
"yourKeyIsUnregistered":"Khóa của bạn đã bị xóa",
|
"yourKeyIsUnregistered":"Khóa của bạn đã bị xóa",
|
||||||
"yourKeyIsVerified":"Chìa khóa của bạn đã được kiểm tra thành công",
|
"yourKeyIsVerified":"Chìa khóa của bạn đã được kiểm tra thành công",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
|
"yourOffline": "and access your account while you are offline",
|
||||||
"yourPhone":"Số điện thoại của bạn",
|
"yourPhone":"Số điện thoại của bạn",
|
||||||
"yourProfile":"Profile của bạn",
|
"yourProfile":"Profile của bạn",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@
|
|||||||
"notFound":"无法找到:您请求的网页不存在。",
|
"notFound":"无法找到:您请求的网页不存在。",
|
||||||
"noTOTPFound":"No TOTP found",
|
"noTOTPFound":"No TOTP found",
|
||||||
"noU2FKeyFound":"No U2F key found",
|
"noU2FKeyFound":"No U2F key found",
|
||||||
"oidcConsent":"The application %s would like to know:",
|
"oidcConsent":"The application %s would like to:",
|
||||||
"oidcConsents":"OIDC consents",
|
"oidcConsents":"OIDC consents",
|
||||||
"oidcConsentsFull":"OpenID Connect consents",
|
"oidcConsentsFull":"OpenID Connect consents",
|
||||||
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
"oneExpired2Fremoved":"An expired 2F device has been removed!",
|
||||||
@ -273,8 +273,9 @@
|
|||||||
"yourKeyIsUnregistered":"Your key has been unregistered",
|
"yourKeyIsUnregistered":"Your key has been unregistered",
|
||||||
"yourKeyIsVerified":"Your key is verified",
|
"yourKeyIsVerified":"Your key is verified",
|
||||||
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
"yourNewTotpKey":"Your new TOTP key, please test it and enter the code",
|
||||||
|
"yourOffline": "and access your account while you are offline",
|
||||||
"yourPhone":"您的电话号码",
|
"yourPhone":"您的电话号码",
|
||||||
"yourProfile":"您的档案",
|
"yourProfile":"您的档案",
|
||||||
"yourTotpKey":"Your TOTP key",
|
"yourTotpKey":"Your TOTP key",
|
||||||
"yubikey2f":"Yubikey"
|
"yubikey2f":"Yubikey"
|
||||||
}
|
}
|
||||||
|
223
lemonldap-ng-portal/t/32-OIDC-Offline-Session.t
Normal file
223
lemonldap-ng-portal/t/32-OIDC-Offline-Session.t
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
use lib 'inc';
|
||||||
|
use Test::More;
|
||||||
|
use strict;
|
||||||
|
use IO::String;
|
||||||
|
use LWP::UserAgent;
|
||||||
|
use LWP::Protocol::PSGI;
|
||||||
|
use MIME::Base64;
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
require 't/test-lib.pm';
|
||||||
|
}
|
||||||
|
|
||||||
|
my $debug = 'error';
|
||||||
|
|
||||||
|
# Initialization
|
||||||
|
my $op = LLNG::Manager::Test->new( {
|
||||||
|
ini => {
|
||||||
|
logLevel => $debug,
|
||||||
|
domain => 'idp.com',
|
||||||
|
portal => 'http://auth.op.com',
|
||||||
|
authentication => 'Demo',
|
||||||
|
userDB => 'Same',
|
||||||
|
issuerDBOpenIDConnectActivation => 1,
|
||||||
|
issuerDBOpenIDConnectRule => '$uid eq "french"',
|
||||||
|
oidcRPMetaDataExportedVars => {
|
||||||
|
rp => {
|
||||||
|
email => "mail",
|
||||||
|
family_name => "cn",
|
||||||
|
name => "cn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
oidcServiceMetaDataIssuer => "http://auth.op.com",
|
||||||
|
oidcServiceMetaDataAuthorizeURI => "authorize",
|
||||||
|
oidcServiceMetaDataCheckSessionURI => "checksession.html",
|
||||||
|
oidcServiceMetaDataJWKSURI => "jwks",
|
||||||
|
oidcServiceMetaDataEndSessionURI => "logout",
|
||||||
|
oidcServiceMetaDataRegistrationURI => "register",
|
||||||
|
oidcServiceMetaDataTokenURI => "token",
|
||||||
|
oidcServiceMetaDataUserInfoURI => "userinfo",
|
||||||
|
oidcServiceAllowHybridFlow => 1,
|
||||||
|
oidcServiceAllowImplicitFlow => 1,
|
||||||
|
oidcServiceAllowDynamicRegistration => 1,
|
||||||
|
oidcServiceAllowAuthorizationCodeFlow => 1,
|
||||||
|
oidcRPMetaDataOptions => {
|
||||||
|
rp => {
|
||||||
|
oidcRPMetaDataOptionsDisplayName => "RP",
|
||||||
|
oidcRPMetaDataOptionsIDTokenExpiration => 3600,
|
||||||
|
oidcRPMetaDataOptionsClientID => "rpid",
|
||||||
|
oidcRPMetaDataOptionsAllowOffline => 1,
|
||||||
|
oidcRPMetaDataOptionsIDTokenSignAlg => "HS512",
|
||||||
|
oidcRPMetaDataOptionsClientSecret => "rpsecret",
|
||||||
|
oidcRPMetaDataOptionsUserIDAttr => "",
|
||||||
|
oidcRPMetaDataOptionsAccessTokenExpiration => 3600,
|
||||||
|
oidcRPMetaDataOptionsBypassConsent => 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
oidcOPMetaDataOptions => {},
|
||||||
|
oidcOPMetaDataJSON => {},
|
||||||
|
oidcOPMetaDataJWKS => {},
|
||||||
|
oidcServiceMetaDataAuthnContext => {
|
||||||
|
'loa-4' => 4,
|
||||||
|
'loa-1' => 1,
|
||||||
|
'loa-5' => 5,
|
||||||
|
'loa-2' => 2,
|
||||||
|
'loa-3' => 3
|
||||||
|
},
|
||||||
|
oidcServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAs2jsmIoFuWzMkilJaA8//5/T30cnuzX9GImXUrFR2k9EKTMt
|
||||||
|
GMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8TrH1PHFmHpy8/qE/S5OhinIpIi7eb
|
||||||
|
ABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH1caJ8lmiERFj7IvNKqEhzAk0pyDr
|
||||||
|
8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdykX5rx0h5SslG3jVWYhZ/SOb2aIzO
|
||||||
|
r0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO8093X5VVk9vaPRg0zxJQ0Do0YLyzkR
|
||||||
|
isSAIFb0tdKuDnjRGK6y/N2j6At2HjkxntbtGQIDAQABAoIBADYq6LxJd977LWy3
|
||||||
|
0HT9nboFPIf+SM2qSEc/S5Po+6ipJBA4ZlZCMf7dHa6znet1TDpqA9iQ4YcqIHMH
|
||||||
|
6xZNQ7hhgSAzG9TrXBHqP+djDlrrGWotvjuy0IfS9ixFnnLWjrtAH9afRWLuG+a/
|
||||||
|
NHNC1M6DiiTE0TzL/lpt/zzut3CNmWzH+t19X6UsxUg95AzooEeewEYkv25eumWD
|
||||||
|
mfQZfCtSlIw1sp/QwxeJa/6LJw7KcPZ1wXUm1BN0b9eiKt9Cmni1MS7elgpZlgGt
|
||||||
|
xtfGTZtNLQ7bgDiM8MHzUfPBhbceNSIx2BeCuOCs/7eaqgpyYHBbAbuBQex2H61l
|
||||||
|
Lcc3Tz0CgYEA4Kx/avpCPxnvsJ+nHVQm5d/WERuDxk4vH1DNuCYBvXTdVCGADf6a
|
||||||
|
F5No1JcTH3nPTyPWazOyGdT9LcsEJicLyD8vCM6hBFstG4XjqcAuqG/9DRsElpHQ
|
||||||
|
yi1zc5DNP7Vxmiz9wII0Mjy0abYKtxnXh9YK4a9g6wrcTpvShhIcIb8CgYEAzGzG
|
||||||
|
lorVCfX9jXULIznnR/uuP5aSnTEsn0xJeqTlbW0RFWLdj8aIL1peirh1X89HroB9
|
||||||
|
GeTNqEJXD+3CVL2cx+BRggMDUmEz4hR59meZCDGUyT5fex4LIsceb/ESUl2jo6Sw
|
||||||
|
HXwWbN67rQ55N4oiOcOppsGxzOHkl5HdExKidycCgYEAr5Qev2tz+fw65LzfzHvH
|
||||||
|
Kj4S/KuT/5V6He731cFd+sEpdmX3vPgLVAFPG1Q1DZQT/rTzDDQKK0XX1cGiLG63
|
||||||
|
NnaqOye/jbfzOF8Z277kt51NFMDYhRLPKDD82IOA4xjY/rPKWndmcxwdob8yAIWh
|
||||||
|
efY76sMz6ntCT+xWSZA9i+ECgYBWMZM2TIlxLsBfEbfFfZewOUWKWEGvd9l5vV/K
|
||||||
|
D5cRIYivfMUw5yPq2267jPUolayCvniBH4E7beVpuPVUZ7KgcEvNxtlytbt7muil
|
||||||
|
5Z6X3tf+VodJ0Swe2NhTmNEB26uwxzLe68BE3VFCsbSYn2y48HAq+MawPZr18bHG
|
||||||
|
ZfgMxwKBgHHRg6HYqF5Pegzk1746uH2G+OoCovk5ylGGYzcH2ghWTK4agCHfBcDt
|
||||||
|
EYqYAev/l82wi+OZ5O8U+qjFUpT1CVeUJdDs0o5u19v0UJjunU1cwh9jsxBZAWLy
|
||||||
|
PAGd6SWf4S3uQCTw6dLeMna25YIlPh5qPA6I/pAahe8e3nSu2ckl
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
",
|
||||||
|
oidcServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2jsmIoFuWzMkilJaA8/
|
||||||
|
/5/T30cnuzX9GImXUrFR2k9EKTMtGMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8T
|
||||||
|
rH1PHFmHpy8/qE/S5OhinIpIi7ebABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH
|
||||||
|
1caJ8lmiERFj7IvNKqEhzAk0pyDr8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdy
|
||||||
|
kX5rx0h5SslG3jVWYhZ/SOb2aIzOr0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO80
|
||||||
|
93X5VVk9vaPRg0zxJQ0Do0YLyzkRisSAIFb0tdKuDnjRGK6y/N2j6At2Hjkxntbt
|
||||||
|
GQIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
my $res;
|
||||||
|
|
||||||
|
my $url = "/";
|
||||||
|
my $query = "user=french&password=french";
|
||||||
|
$res = $op->_post(
|
||||||
|
"/",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => length($query),
|
||||||
|
);
|
||||||
|
my $idpId = expectCookie($res);
|
||||||
|
|
||||||
|
my $query =
|
||||||
|
"response_type=code&scope=openid%20profile%20email%20offline_access&"
|
||||||
|
. "client_id=rpid&state=af0ifjsldkj&redirect_uri=http%3A%2F%2Ftest%2F";
|
||||||
|
$res = $op->_get(
|
||||||
|
"/oauth2/authorize",
|
||||||
|
query => "$query",
|
||||||
|
accept => 'text/html',
|
||||||
|
cookie => "lemonldap=$idpId",
|
||||||
|
);
|
||||||
|
|
||||||
|
my ($code) = expectRedirection( $res, qr#http://test/.*code=([^\&]*)# );
|
||||||
|
|
||||||
|
$query =
|
||||||
|
"grant_type=authorization_code&code=$code&redirect_uri=http%3A%2F%2Ftest%2F";
|
||||||
|
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/token",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => length($query),
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
my $json = expectJSON($res);
|
||||||
|
my $access_token = $json->{access_token};
|
||||||
|
my $refresh_token = $json->{refresh_token};
|
||||||
|
my $id_token = $json->{id_token};
|
||||||
|
ok( $access_token, "Got access token" );
|
||||||
|
ok( $refresh_token, "Got refresh token" );
|
||||||
|
ok( $id_token, "Got ID token" );
|
||||||
|
count(3);
|
||||||
|
|
||||||
|
# Get userinfo
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/userinfo",
|
||||||
|
IO::String->new(''),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => 0,
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Bearer " . $access_token,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
$json = expectJSON($res);
|
||||||
|
|
||||||
|
ok( $json->{'name'} eq "Frédéric Accents", 'Got User Info' );
|
||||||
|
count(1);
|
||||||
|
|
||||||
|
$op->logout($idpId);
|
||||||
|
|
||||||
|
# Refresh access token
|
||||||
|
|
||||||
|
$query = "grant_type=refresh_token&refresh_token=$refresh_token";
|
||||||
|
|
||||||
|
|
||||||
|
ok(
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/token",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => length($query),
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Refresh access token"
|
||||||
|
);
|
||||||
|
count(1);
|
||||||
|
expectOK($res);
|
||||||
|
|
||||||
|
$json = expectJSON($res);
|
||||||
|
$access_token = $json->{access_token};
|
||||||
|
$refresh_token = $json->{refresh_token};
|
||||||
|
$id_token = $json->{id_token};
|
||||||
|
ok( $access_token, "Got refreshed Access token" );
|
||||||
|
ok( $id_token, "Got refreshed ID token" );
|
||||||
|
ok( !defined $refresh_token, "Refresh token not present" );
|
||||||
|
count(3);
|
||||||
|
|
||||||
|
## Get userinfo again
|
||||||
|
ok(
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/userinfo",
|
||||||
|
IO::String->new(''),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => 0,
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Bearer " . $access_token,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Post new access token"
|
||||||
|
);
|
||||||
|
expectOK($res);
|
||||||
|
count(1);
|
||||||
|
$json = expectJSON($res);
|
||||||
|
|
||||||
|
ok( $json->{name} eq "Frédéric Accents", "Correct user info" );
|
||||||
|
count(1);
|
||||||
|
|
||||||
|
clean_sessions();
|
||||||
|
done_testing( count() );
|
||||||
|
|
264
lemonldap-ng-portal/t/32-OIDC-Refresh-Token.t
Normal file
264
lemonldap-ng-portal/t/32-OIDC-Refresh-Token.t
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
use lib 'inc';
|
||||||
|
use Test::More;
|
||||||
|
use strict;
|
||||||
|
use IO::String;
|
||||||
|
use LWP::UserAgent;
|
||||||
|
use LWP::Protocol::PSGI;
|
||||||
|
use MIME::Base64;
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
require 't/test-lib.pm';
|
||||||
|
}
|
||||||
|
|
||||||
|
my $debug = 'error';
|
||||||
|
|
||||||
|
# Initialization
|
||||||
|
my $op = LLNG::Manager::Test->new( {
|
||||||
|
ini => {
|
||||||
|
logLevel => $debug,
|
||||||
|
domain => 'idp.com',
|
||||||
|
portal => 'http://auth.op.com',
|
||||||
|
authentication => 'Demo',
|
||||||
|
userDB => 'Same',
|
||||||
|
issuerDBOpenIDConnectActivation => 1,
|
||||||
|
issuerDBOpenIDConnectRule => '$uid eq "french"',
|
||||||
|
oidcRPMetaDataExportedVars => {
|
||||||
|
rp => {
|
||||||
|
email => "mail",
|
||||||
|
family_name => "cn",
|
||||||
|
name => "cn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
oidcServiceMetaDataIssuer => "http://auth.op.com",
|
||||||
|
oidcServiceMetaDataAuthorizeURI => "authorize",
|
||||||
|
oidcServiceMetaDataCheckSessionURI => "checksession.html",
|
||||||
|
oidcServiceMetaDataJWKSURI => "jwks",
|
||||||
|
oidcServiceMetaDataEndSessionURI => "logout",
|
||||||
|
oidcServiceMetaDataRegistrationURI => "register",
|
||||||
|
oidcServiceMetaDataTokenURI => "token",
|
||||||
|
oidcServiceMetaDataUserInfoURI => "userinfo",
|
||||||
|
oidcServiceAllowHybridFlow => 1,
|
||||||
|
oidcServiceAllowImplicitFlow => 1,
|
||||||
|
oidcServiceAllowDynamicRegistration => 1,
|
||||||
|
oidcServiceAllowAuthorizationCodeFlow => 1,
|
||||||
|
oidcRPMetaDataOptions => {
|
||||||
|
rp => {
|
||||||
|
oidcRPMetaDataOptionsDisplayName => "RP",
|
||||||
|
oidcRPMetaDataOptionsIDTokenExpiration => 3600,
|
||||||
|
oidcRPMetaDataOptionsClientID => "rpid",
|
||||||
|
oidcRPMetaDataOptionsAllowOffline => 1,
|
||||||
|
oidcRPMetaDataOptionsIDTokenSignAlg => "HS512",
|
||||||
|
oidcRPMetaDataOptionsClientSecret => "rpsecret",
|
||||||
|
oidcRPMetaDataOptionsUserIDAttr => "",
|
||||||
|
oidcRPMetaDataOptionsAccessTokenExpiration => 1,
|
||||||
|
oidcRPMetaDataOptionsBypassConsent => 1,
|
||||||
|
oidcRPMetaDataOptionsRefreshToken => 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
oidcOPMetaDataOptions => {},
|
||||||
|
oidcOPMetaDataJSON => {},
|
||||||
|
oidcOPMetaDataJWKS => {},
|
||||||
|
oidcServiceMetaDataAuthnContext => {
|
||||||
|
'loa-4' => 4,
|
||||||
|
'loa-1' => 1,
|
||||||
|
'loa-5' => 5,
|
||||||
|
'loa-2' => 2,
|
||||||
|
'loa-3' => 3
|
||||||
|
},
|
||||||
|
oidcServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAs2jsmIoFuWzMkilJaA8//5/T30cnuzX9GImXUrFR2k9EKTMt
|
||||||
|
GMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8TrH1PHFmHpy8/qE/S5OhinIpIi7eb
|
||||||
|
ABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH1caJ8lmiERFj7IvNKqEhzAk0pyDr
|
||||||
|
8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdykX5rx0h5SslG3jVWYhZ/SOb2aIzO
|
||||||
|
r0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO8093X5VVk9vaPRg0zxJQ0Do0YLyzkR
|
||||||
|
isSAIFb0tdKuDnjRGK6y/N2j6At2HjkxntbtGQIDAQABAoIBADYq6LxJd977LWy3
|
||||||
|
0HT9nboFPIf+SM2qSEc/S5Po+6ipJBA4ZlZCMf7dHa6znet1TDpqA9iQ4YcqIHMH
|
||||||
|
6xZNQ7hhgSAzG9TrXBHqP+djDlrrGWotvjuy0IfS9ixFnnLWjrtAH9afRWLuG+a/
|
||||||
|
NHNC1M6DiiTE0TzL/lpt/zzut3CNmWzH+t19X6UsxUg95AzooEeewEYkv25eumWD
|
||||||
|
mfQZfCtSlIw1sp/QwxeJa/6LJw7KcPZ1wXUm1BN0b9eiKt9Cmni1MS7elgpZlgGt
|
||||||
|
xtfGTZtNLQ7bgDiM8MHzUfPBhbceNSIx2BeCuOCs/7eaqgpyYHBbAbuBQex2H61l
|
||||||
|
Lcc3Tz0CgYEA4Kx/avpCPxnvsJ+nHVQm5d/WERuDxk4vH1DNuCYBvXTdVCGADf6a
|
||||||
|
F5No1JcTH3nPTyPWazOyGdT9LcsEJicLyD8vCM6hBFstG4XjqcAuqG/9DRsElpHQ
|
||||||
|
yi1zc5DNP7Vxmiz9wII0Mjy0abYKtxnXh9YK4a9g6wrcTpvShhIcIb8CgYEAzGzG
|
||||||
|
lorVCfX9jXULIznnR/uuP5aSnTEsn0xJeqTlbW0RFWLdj8aIL1peirh1X89HroB9
|
||||||
|
GeTNqEJXD+3CVL2cx+BRggMDUmEz4hR59meZCDGUyT5fex4LIsceb/ESUl2jo6Sw
|
||||||
|
HXwWbN67rQ55N4oiOcOppsGxzOHkl5HdExKidycCgYEAr5Qev2tz+fw65LzfzHvH
|
||||||
|
Kj4S/KuT/5V6He731cFd+sEpdmX3vPgLVAFPG1Q1DZQT/rTzDDQKK0XX1cGiLG63
|
||||||
|
NnaqOye/jbfzOF8Z277kt51NFMDYhRLPKDD82IOA4xjY/rPKWndmcxwdob8yAIWh
|
||||||
|
efY76sMz6ntCT+xWSZA9i+ECgYBWMZM2TIlxLsBfEbfFfZewOUWKWEGvd9l5vV/K
|
||||||
|
D5cRIYivfMUw5yPq2267jPUolayCvniBH4E7beVpuPVUZ7KgcEvNxtlytbt7muil
|
||||||
|
5Z6X3tf+VodJ0Swe2NhTmNEB26uwxzLe68BE3VFCsbSYn2y48HAq+MawPZr18bHG
|
||||||
|
ZfgMxwKBgHHRg6HYqF5Pegzk1746uH2G+OoCovk5ylGGYzcH2ghWTK4agCHfBcDt
|
||||||
|
EYqYAev/l82wi+OZ5O8U+qjFUpT1CVeUJdDs0o5u19v0UJjunU1cwh9jsxBZAWLy
|
||||||
|
PAGd6SWf4S3uQCTw6dLeMna25YIlPh5qPA6I/pAahe8e3nSu2ckl
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
",
|
||||||
|
oidcServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2jsmIoFuWzMkilJaA8/
|
||||||
|
/5/T30cnuzX9GImXUrFR2k9EKTMtGMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8T
|
||||||
|
rH1PHFmHpy8/qE/S5OhinIpIi7ebABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH
|
||||||
|
1caJ8lmiERFj7IvNKqEhzAk0pyDr8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdy
|
||||||
|
kX5rx0h5SslG3jVWYhZ/SOb2aIzOr0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO80
|
||||||
|
93X5VVk9vaPRg0zxJQ0Do0YLyzkRisSAIFb0tdKuDnjRGK6y/N2j6At2Hjkxntbt
|
||||||
|
GQIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
my $res;
|
||||||
|
|
||||||
|
my $url = "/";
|
||||||
|
my $query = "user=french&password=french";
|
||||||
|
$res = $op->_post(
|
||||||
|
"/",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => length($query),
|
||||||
|
);
|
||||||
|
my $idpId = expectCookie($res);
|
||||||
|
|
||||||
|
my $query =
|
||||||
|
"response_type=code&scope=openid%20profile%20email&"
|
||||||
|
. "client_id=rpid&state=af0ifjsldkj&redirect_uri=http%3A%2F%2Ftest%2F";
|
||||||
|
$res = $op->_get(
|
||||||
|
"/oauth2/authorize",
|
||||||
|
query => "$query",
|
||||||
|
accept => 'text/html',
|
||||||
|
cookie => "lemonldap=$idpId",
|
||||||
|
);
|
||||||
|
|
||||||
|
my ($code) = expectRedirection( $res, qr#http://test/.*code=([^\&]*)# );
|
||||||
|
|
||||||
|
$query =
|
||||||
|
"grant_type=authorization_code&code=$code&redirect_uri=http%3A%2F%2Ftest%2F";
|
||||||
|
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/token",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'application/json',
|
||||||
|
length => length($query),
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
my $json = expectJSON($res);
|
||||||
|
my $access_token = $json->{access_token};
|
||||||
|
my $refresh_token = $json->{refresh_token};
|
||||||
|
my $id_token = $json->{id_token};
|
||||||
|
ok( $access_token, "Got access token" );
|
||||||
|
ok( $refresh_token, "Got refresh token" );
|
||||||
|
ok( $id_token, "Got ID token" );
|
||||||
|
|
||||||
|
# Get userinfo
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/userinfo",
|
||||||
|
IO::String->new(''),
|
||||||
|
accept => 'application/json',
|
||||||
|
length => 0,
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Bearer " . $access_token,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
$json = expectJSON($res);
|
||||||
|
|
||||||
|
ok( $json->{'name'} eq "Frédéric Accents", 'Got User Info' );
|
||||||
|
|
||||||
|
sleep(2);
|
||||||
|
|
||||||
|
# Access token should have expired
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/userinfo",
|
||||||
|
IO::String->new(''),
|
||||||
|
accept => 'application/json',
|
||||||
|
length => 0,
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Bearer " . $access_token,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
is( $res->[0], 401, "Access token refused" );
|
||||||
|
|
||||||
|
# Refresh access token
|
||||||
|
|
||||||
|
$query = "grant_type=refresh_token&refresh_token=$refresh_token";
|
||||||
|
|
||||||
|
ok(
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/token",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => length($query),
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Refresh access token"
|
||||||
|
);
|
||||||
|
expectOK($res);
|
||||||
|
|
||||||
|
$json = expectJSON($res);
|
||||||
|
$access_token = $json->{access_token};
|
||||||
|
$id_token = $json->{id_token};
|
||||||
|
ok( $access_token, "Got refreshed Access token" );
|
||||||
|
ok( $id_token, "Got refreshed ID token" );
|
||||||
|
ok( !defined $json->{refresh_token}, "Refresh token not present" );
|
||||||
|
|
||||||
|
# Try refreshed access token
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/userinfo",
|
||||||
|
IO::String->new(''),
|
||||||
|
accept => 'application/json',
|
||||||
|
length => 0,
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Bearer " . $access_token,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
$json = expectJSON($res);
|
||||||
|
|
||||||
|
ok( $json->{'name'} eq "Frédéric Accents", 'Got User Info' );
|
||||||
|
|
||||||
|
# Check failure conditions
|
||||||
|
$op->logout($idpId);
|
||||||
|
|
||||||
|
# Refresh access token
|
||||||
|
|
||||||
|
$query = "grant_type=refresh_token&refresh_token=$refresh_token";
|
||||||
|
|
||||||
|
ok(
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/token",
|
||||||
|
IO::String->new($query),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => length($query),
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Refresh access token"
|
||||||
|
);
|
||||||
|
|
||||||
|
is( $res->[0], 401, "Cannot use refresh token tied to expired session" );
|
||||||
|
|
||||||
|
## Get userinfo again
|
||||||
|
ok(
|
||||||
|
$res = $op->_post(
|
||||||
|
"/oauth2/userinfo",
|
||||||
|
IO::String->new(''),
|
||||||
|
accept => 'text/html',
|
||||||
|
length => 0,
|
||||||
|
custom => {
|
||||||
|
HTTP_AUTHORIZATION => "Bearer " . $access_token,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"Post new access token"
|
||||||
|
);
|
||||||
|
is( $res->[0], 401,
|
||||||
|
"Cannot use refreshed access token tied to expired session" );
|
||||||
|
|
||||||
|
clean_sessions();
|
||||||
|
done_testing();
|
||||||
|
|
@ -148,7 +148,7 @@ ok(
|
|||||||
accept => 'text/html',
|
accept => 'text/html',
|
||||||
cookie => "lemonldap=$idpId",
|
cookie => "lemonldap=$idpId",
|
||||||
),
|
),
|
||||||
"Get authorization code"
|
"Get authorization code for rp1"
|
||||||
);
|
);
|
||||||
count(1);
|
count(1);
|
||||||
|
|
||||||
@ -168,17 +168,33 @@ ok(
|
|||||||
HTTP_AUTHORIZATION => "Basic " . encode_base64("rp2id:rp2secret"),
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rp2id:rp2secret"),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
"Post token"
|
"Post token on wrong RP"
|
||||||
);
|
);
|
||||||
count(1);
|
count(1);
|
||||||
|
|
||||||
# Expect an invalid request
|
# Expect an invalid request
|
||||||
is( $res->[0], 400 );
|
is( $res->[0], 400, "Got invalid request" );
|
||||||
count(1);
|
count(1);
|
||||||
|
|
||||||
|
# Get new code for RP1
|
||||||
|
my $query =
|
||||||
|
"response_type=code&scope=openid%20profile%20email&client_id=rpid&state=af0ifjsldkj&redirect_uri=http%3A%2F%2Frp.com%2F";
|
||||||
|
ok(
|
||||||
|
$res = $op->_get(
|
||||||
|
"/oauth2/authorize",
|
||||||
|
query => "$query",
|
||||||
|
accept => 'text/html',
|
||||||
|
cookie => "lemonldap=$idpId",
|
||||||
|
),
|
||||||
|
"Get authorization code again"
|
||||||
|
);
|
||||||
|
count(1);
|
||||||
|
|
||||||
|
my ($code) = expectRedirection( $res, qr#http://rp\.com/.*code=([^\&]*)# );
|
||||||
|
|
||||||
# Play code on RP1
|
# Play code on RP1
|
||||||
$query =
|
$query =
|
||||||
"grant_type=authorization_code&code=$code&redirect_uri=http%3A%2F%2Frp2.com%2F";
|
"grant_type=authorization_code&code=$code&redirect_uri=http%3A%2F%2Frp.com%2F";
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
$res = $op->_post(
|
$res = $op->_post(
|
||||||
@ -190,7 +206,7 @@ ok(
|
|||||||
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
"Post token"
|
"Post auth code on correct RP"
|
||||||
);
|
);
|
||||||
count(1);
|
count(1);
|
||||||
$res = expectJSON($res);
|
$res = expectJSON($res);
|
||||||
@ -209,10 +225,10 @@ ok(
|
|||||||
HTTP_AUTHORIZATION => "Bearer " . $token,
|
HTTP_AUTHORIZATION => "Bearer " . $token,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
"Post userinfo"
|
"post to userinfo with expired access token"
|
||||||
);
|
);
|
||||||
count(1);
|
count(1);
|
||||||
is( $res->[0], 401, "Access denied with expired token" );
|
ok( $res->[0] == 401, "Access denied with expired token" );
|
||||||
count(1);
|
count(1);
|
||||||
|
|
||||||
clean_sessions();
|
clean_sessions();
|
||||||
|
Loading…
Reference in New Issue
Block a user