Merge branch 'fix-idprules-oidc-2753' into 'v2.0'

Add IDP resolution rules for CAS/OIDC (#2753)

See merge request lemonldap-ng/lemonldap-ng!267
This commit is contained in:
Maxime Besson 2022-05-19 15:00:44 +00:00
commit 694fb4e440
27 changed files with 362 additions and 79 deletions

View File

@ -63,24 +63,49 @@ Then, go in ``CAS parameters``:
- **Authentication level**: authentication level for this module. - **Authentication level**: authentication level for this module.
Then create the list of CAS servers in the manager. For each, set: Then create the list of CAS servers in the manager.
Options
~~~~~~~
- **Server URL** *(required)*: CAS server URL (must use https://) - **Server URL** *(required)*: CAS server URL (must use https://)
- **Renew authentication** *(default: disabled)*: force authentication - **Renew authentication** *(default: disabled)*: force authentication
renewal on CAS server renewal on CAS server
- **Gateways authentication** *(default: disabled)*: force transparent - **Gateways authentication** *(default: disabled)*: force transparent
authentication on CAS server authentication on CAS server
- **Display Name**: Name to display. Required if you have more than 1
CAS server declared Proxied services
- **Icon**: Path to CAS Server icon. Used only if you have more than 1 ~~~~~~~~~~~~~~~~
CAS server declared
- **Order**: Number to sort CAS Servers display In this section, set the list of services for which a proxy ticket is
- **Proxied services**: list of services for which a proxy ticket is
requested: requested:
- **Key**: Service ID - **Key**: Service ID
- **Value** Service URL (CAS service identifier) - **Value** Service URL (CAS service identifier)
Display
~~~~~~~
- **Display Name**: Name to display. Required if you have more than 1
CAS server declared
- **Icon**: Path to CAS Server icon. Used only if you have more than 1
CAS server declared
- **Resolution Rule**: rule that will be applied to preselect a CAS server for
a user. You have access to all environment variable *(like user IP address)*
and all session keys.
For example, to preselect this server for users coming from 129.168.0.0/16
network
::
$ENV{REMOTE_ADDR} =~ /^192\.168/
To preselect this server when the ``MY_SRV`` :doc:`choice <authchoice>` is selected ::
$_choice eq "MY_SRV"
- **Order**: Number to sort CAS Servers display
.. tip:: .. tip::

View File

@ -210,7 +210,8 @@ So you can define by example:
Options Options
^^^^^^^ ^^^^^^^
- **Configuration**: Configuration
"""""""""""""
- **Configuration endpoint**: URL of OP configuration endpoint - **Configuration endpoint**: URL of OP configuration endpoint
- **JWKS data timeout**: After this time, LL::NG will do a request - **JWKS data timeout**: After this time, LL::NG will do a request
@ -222,8 +223,8 @@ Options
on an application, or if you need the id_token_hint parameter when on an application, or if you need the id_token_hint parameter when
using logout. using logout.
- **Protocol**: Protocol
""""""""
- **Scope**: Value of scope parameter (example: openid profile). The - **Scope**: Value of scope parameter (example: openid profile). The
``openid`` scope is mandatory. ``openid`` scope is mandatory.
- **Display**: Value of display parameter (example: page) - **Display**: Value of display parameter (example: page)
@ -241,10 +242,26 @@ Options
- **Use Nonce**: If enabled, a nonce will be sent, and verified from - **Use Nonce**: If enabled, a nonce will be sent, and verified from
the ID Token the ID Token
- **Display**: Display
"""""""
- **Display name**: Name of the application - **Display name**: Name of the application
- **Logo**: Logo of the application - **Logo**: Logo of the application
- **Resolution Rule**: rule that will be applied to preselect an OP
for a user. You have access to all environment variable *(like user
IP address)* and all session keys.
For example, to preselect this OP for users coming from 129.168.0.0/16
network
::
$ENV{REMOTE_ADDR} =~ /^192\.168/
To preselect this OP when the ``MY_OP`` :doc:`choice <authchoice>` is selected ::
$_choice eq "MY_OP"
- **Order**: Number to sort buttons - **Order**: Number to sort buttons

View File

@ -111,20 +111,6 @@ For each attribute, you can set:
Options Options
^^^^^^^ ^^^^^^^
General options
'''''''''''''''
- **Resolution Rule**: rule that will be applied to preselect an IDP
for a user. You have access to all environment variable *(like user
IP address)* and all session keys.
For example, to preselect this IDP for users coming from 129.168.0.0/16
network and member of "admin" group:
::
$ENV{REMOTE_ADDR} =~ /^192\.168/ and $groups =~ /\badmin\b/
Authentication request Authentication request
'''''''''''''''''''''' ''''''''''''''''''''''
@ -212,8 +198,6 @@ Used only if at least 2 SAML Identity Providers are declared
- **Display name**: Name of the IDP - **Display name**: Name of the IDP
- **Logo**: Logo of the IDP - **Logo**: Logo of the IDP
- **Order**: Number used for sorting IDP display
.. tip:: .. tip::
@ -222,6 +206,23 @@ Used only if at least 2 SAML Identity Providers are declared
icon file name directly in the field and copy the logo file in portal icon file name directly in the field and copy the logo file in portal
icons directory icons directory
- **Resolution Rule**: rule that will be applied to preselect an IDP
for a user. You have access to all environment variable *(like user
IP address)* and all session keys.
For example, to preselect this IDP for users coming from 129.168.0.0/16
network
::
$ENV{REMOTE_ADDR} =~ /^192\.168/
To preselect this IDP when the ``MY_IDP`` :doc:`choice <authchoice>` is selected ::
$_choice eq "MY_IDP"
- **Order**: Number used for sorting IDP display
.. |image0| image:: /documentation/manager-saml-metadata.png .. |image0| image:: /documentation/manager-saml-metadata.png
:class: align-center :class: align-center
.. |image1| image:: /documentation/manager-saml-attributes.png .. |image1| image:: /documentation/manager-saml-attributes.png

View File

@ -25,8 +25,8 @@ our $doubleHashKeys = 'issuerDBGetParameters';
our $simpleHashKeys = '(?:(?:c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)|l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|(?:(?:d(?:emo|bi)|webID)E|e)xportedVar|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|OPMetaDataJ(?:SON|WKS))|penIdExportedVars)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|S(?:MTPTLSOpts|SLVarIf))'; our $simpleHashKeys = '(?:(?:c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)|l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|(?:(?:d(?:emo|bi)|webID)E|e)xportedVar|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|OPMetaDataJ(?:SON|WKS))|penIdExportedVars)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|S(?:MTPTLSOpts|SLVarIf))';
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s'; our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:(?:UserAttribut|Servic|Rul)e|AuthnLevel)|(?:ExportedVar|Macro)s)'; our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:(?:UserAttribut|Servic|Rul)e|AuthnLevel)|(?:ExportedVar|Macro)s)';
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)'; our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:Re(?:solutionRule|new)|ProxiedServices|DisplayName|SortNumber|Gateway|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)|(?:ResolutionRul|MaxAg)e|TokenEndpointAuthMethod|(?:JWKSTimeou|Promp)t|I(?:DTokenMaxAge|con)|U(?:iLocales|seNonce)|Display(?:Name)?|AcrValues)|ExportedVars|J(?:SON|WKS))';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:llow(?:(?:ClientCredentials|Password)Grant|Offline)|ccessToken(?:Expiration|SignAlg|Claims|JWT)|uth(?:orizationCodeExpiration|nLevel)|dditionalAudiences)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|UserI(?:nfoSignAlg|DAttr)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims)|(?:ExportedVar|ScopeRule|Macro)s)'; our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:llow(?:(?:ClientCredentials|Password)Grant|Offline)|ccessToken(?:Expiration|SignAlg|Claims|JWT)|uth(?:orizationCodeExpiration|nLevel)|dditionalAudiences)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|UserI(?:nfoSignAlg|DAttr)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims)|(?:ExportedVar|ScopeRule|Macro)s)';
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|UserAttribut|DisplayNam)e|S(?:ign(?:S[LS]OMessage|atureMethod)|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(?:ign(?:S[LS]OMessage|atureMethod)|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(?:S(?:ign(?:S[LS]OMessage|atureMethod)|essionNotOnOrAfterTimeout)|N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|AuthnLevel|ForceUTF8)|(?:ExportedAttribute|Macro)s|XML)'; our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:S(?:ign(?:S[LS]OMessage|atureMethod)|essionNotOnOrAfterTimeout)|N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|AuthnLevel|ForceUTF8)|(?:ExportedAttribute|Macro)s|XML)';

View File

@ -797,6 +797,10 @@ sub attributes {
'default' => 0, 'default' => 0,
'type' => 'bool' 'type' => 'bool'
}, },
'casSrvMetaDataOptionsResolutionRule' => {
'default' => '',
'type' => 'longtext'
},
'casSrvMetaDataOptionsSortNumber' => { 'casSrvMetaDataOptionsSortNumber' => {
'type' => 'int' 'type' => 'int'
}, },
@ -2277,6 +2281,10 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'oidcOPMetaDataOptionsPrompt' => { 'oidcOPMetaDataOptionsPrompt' => {
'type' => 'text' 'type' => 'text'
}, },
'oidcOPMetaDataOptionsResolutionRule' => {
'default' => '',
'type' => 'longtext'
},
'oidcOPMetaDataOptionsScope' => { 'oidcOPMetaDataOptionsScope' => {
'default' => 'openid profile', 'default' => 'openid profile',
'type' => 'text' 'type' => 'text'

View File

@ -3673,6 +3673,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
type => 'int', type => 'int',
documentation => 'Number to sort buttons', documentation => 'Number to sort buttons',
}, },
casSrvMetaDataOptionsResolutionRule => {
type => 'longtext',
default => '',
},
# Fake attribute: used by manager REST API to agglomerate all nodes # Fake attribute: used by manager REST API to agglomerate all nodes
# related to a CAS IDP partner # related to a CAS IDP partner
@ -4372,6 +4376,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
oidcOPMetaDataOptionsIcon => { type => 'text', }, oidcOPMetaDataOptionsIcon => { type => 'text', },
oidcOPMetaDataOptionsStoreIDToken => { type => 'bool', default => 0 }, oidcOPMetaDataOptionsStoreIDToken => { type => 'bool', default => 0 },
oidcOPMetaDataOptionsSortNumber => { type => 'int', }, oidcOPMetaDataOptionsSortNumber => { type => 'int', },
oidcOPMetaDataOptionsResolutionRule => {
type => 'longtext',
default => '',
},
# OpenID Connect relying parties # OpenID Connect relying parties
oidcRPMetaDataExportedVars => { oidcRPMetaDataExportedVars => {

View File

@ -82,7 +82,6 @@ sub cTrees {
help => 'authsaml.html#options', help => 'authsaml.html#options',
form => 'simpleInputContainer', form => 'simpleInputContainer',
nodes => [ nodes => [
'samlIDPMetaDataOptionsResolutionRule',
'samlIDPMetaDataOptionsNameIDFormat', 'samlIDPMetaDataOptionsNameIDFormat',
'samlIDPMetaDataOptionsForceAuthn', 'samlIDPMetaDataOptionsForceAuthn',
'samlIDPMetaDataOptionsIsPassive', 'samlIDPMetaDataOptionsIsPassive',
@ -98,6 +97,7 @@ sub cTrees {
nodes => [ nodes => [
"samlIDPMetaDataOptionsDisplayName", "samlIDPMetaDataOptionsDisplayName",
"samlIDPMetaDataOptionsIcon", "samlIDPMetaDataOptionsIcon",
'samlIDPMetaDataOptionsResolutionRule',
"samlIDPMetaDataOptionsSortNumber" "samlIDPMetaDataOptionsSortNumber"
] ]
} }
@ -186,6 +186,7 @@ sub cTrees {
nodes => [ nodes => [
'oidcOPMetaDataOptionsDisplayName', 'oidcOPMetaDataOptionsDisplayName',
'oidcOPMetaDataOptionsIcon', 'oidcOPMetaDataOptionsIcon',
'oidcOPMetaDataOptionsResolutionRule',
'oidcOPMetaDataOptionsSortNumber' 'oidcOPMetaDataOptionsSortNumber'
] ]
}, },
@ -285,6 +286,7 @@ sub cTrees {
nodes => [ nodes => [
'casSrvMetaDataOptionsDisplayName', 'casSrvMetaDataOptionsDisplayName',
'casSrvMetaDataOptionsIcon', 'casSrvMetaDataOptionsIcon',
'casSrvMetaDataOptionsResolutionRule',
'casSrvMetaDataOptionsSortNumber', 'casSrvMetaDataOptionsSortNumber',
] ]
}, },

View File

@ -146,6 +146,13 @@ function templates(tpl,key) {
"id" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsIcon", "id" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsIcon",
"title" : "casSrvMetaDataOptionsIcon" "title" : "casSrvMetaDataOptionsIcon"
}, },
{
"default" : "",
"get" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsResolutionRule",
"id" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsResolutionRule",
"title" : "casSrvMetaDataOptionsResolutionRule",
"type" : "longtext"
},
{ {
"get" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsSortNumber", "get" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsSortNumber",
"id" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsSortNumber", "id" : tpl+"s/"+key+"/"+"casSrvMetaDataOptionsSortNumber",
@ -362,6 +369,13 @@ function templates(tpl,key) {
"id" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsIcon", "id" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsIcon",
"title" : "oidcOPMetaDataOptionsIcon" "title" : "oidcOPMetaDataOptionsIcon"
}, },
{
"default" : "",
"get" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsResolutionRule",
"id" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsResolutionRule",
"title" : "oidcOPMetaDataOptionsResolutionRule",
"type" : "longtext"
},
{ {
"get" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsSortNumber", "get" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsSortNumber",
"id" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsSortNumber", "id" : tpl+"s/"+key+"/"+"oidcOPMetaDataOptionsSortNumber",
@ -976,13 +990,6 @@ function templates(tpl,key) {
}, },
{ {
"_nodes" : [ "_nodes" : [
{
"default" : "",
"get" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsResolutionRule",
"id" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsResolutionRule",
"title" : "samlIDPMetaDataOptionsResolutionRule",
"type" : "longtext"
},
{ {
"default" : "", "default" : "",
"get" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsNameIDFormat", "get" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsNameIDFormat",
@ -1114,6 +1121,13 @@ function templates(tpl,key) {
"id" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsIcon", "id" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsIcon",
"title" : "samlIDPMetaDataOptionsIcon" "title" : "samlIDPMetaDataOptionsIcon"
}, },
{
"default" : "",
"get" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsResolutionRule",
"id" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsResolutionRule",
"title" : "samlIDPMetaDataOptionsResolutionRule",
"type" : "longtext"
},
{ {
"get" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsSortNumber", "get" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsSortNumber",
"id" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsSortNumber", "id" : tpl+"s/"+key+"/"+"samlIDPMetaDataOptionsSortNumber",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"مسارالأيقونة", "casSrvMetaDataOptionsIcon":"مسارالأيقونة",
"casSrvMetaDataOptionsProxiedServices":"خدمات البروكسي", "casSrvMetaDataOptionsProxiedServices":"خدمات البروكسي",
"casSrvMetaDataOptionsRenew":"تجديد إثبات الهوية", "casSrvMetaDataOptionsRenew":"تجديد إثبات الهوية",
"casSrvMetaDataOptionsResolutionRule":"حل القاعدة",
"casSrvMetaDataOptionsSortNumber":"Order", "casSrvMetaDataOptionsSortNumber":"Order",
"casSrvMetaDataOptionsUrl":" يو أر ل الخادم", "casSrvMetaDataOptionsUrl":" يو أر ل الخادم",
"casSrvName":"اسم خادم كاس", "casSrvName":"اسم خادم كاس",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"الحد الأقصى للعمر", "oidcOPMetaDataOptionsMaxAge":"الحد الأقصى للعمر",
"oidcOPMetaDataOptionsPrompt":"عاجل", "oidcOPMetaDataOptionsPrompt":"عاجل",
"oidcOPMetaDataOptionsProtocol":"بروتوكول", "oidcOPMetaDataOptionsProtocol":"بروتوكول",
"oidcOPMetaDataOptionsResolutionRule":"حل القاعدة",
"oidcOPMetaDataOptionsScope":"نطاق", "oidcOPMetaDataOptionsScope":"نطاق",
"oidcOPMetaDataOptionsSortNumber":"Order", "oidcOPMetaDataOptionsSortNumber":"Order",
"oidcOPMetaDataOptionsStoreIDToken":"مخزن تعريف التوكن", "oidcOPMetaDataOptionsStoreIDToken":"مخزن تعريف التوكن",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"Icon path", "casSrvMetaDataOptionsIcon":"Icon path",
"casSrvMetaDataOptionsProxiedServices":"Proxied services", "casSrvMetaDataOptionsProxiedServices":"Proxied services",
"casSrvMetaDataOptionsRenew":"Renew authentication", "casSrvMetaDataOptionsRenew":"Renew authentication",
"casSrvMetaDataOptionsResolutionRule":"Resolution rule",
"casSrvMetaDataOptionsSortNumber":"Order", "casSrvMetaDataOptionsSortNumber":"Order",
"casSrvMetaDataOptionsUrl":"Server URL", "casSrvMetaDataOptionsUrl":"Server URL",
"casSrvName":"CAS Server Name", "casSrvName":"CAS Server Name",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Max age", "oidcOPMetaDataOptionsMaxAge":"Max age",
"oidcOPMetaDataOptionsPrompt":"Prompt", "oidcOPMetaDataOptionsPrompt":"Prompt",
"oidcOPMetaDataOptionsProtocol":"Protocol", "oidcOPMetaDataOptionsProtocol":"Protocol",
"oidcOPMetaDataOptionsResolutionRule":"Resolution rule",
"oidcOPMetaDataOptionsScope":"Scope", "oidcOPMetaDataOptionsScope":"Scope",
"oidcOPMetaDataOptionsSortNumber":"Order", "oidcOPMetaDataOptionsSortNumber":"Order",
"oidcOPMetaDataOptionsStoreIDToken":"Store ID Token", "oidcOPMetaDataOptionsStoreIDToken":"Store ID Token",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"Icon path", "casSrvMetaDataOptionsIcon":"Icon path",
"casSrvMetaDataOptionsProxiedServices":"Servicios proxificados", "casSrvMetaDataOptionsProxiedServices":"Servicios proxificados",
"casSrvMetaDataOptionsRenew":"Renovar autentificación", "casSrvMetaDataOptionsRenew":"Renovar autentificación",
"casSrvMetaDataOptionsResolutionRule":"Resolution rule",
"casSrvMetaDataOptionsSortNumber":"Orden", "casSrvMetaDataOptionsSortNumber":"Orden",
"casSrvMetaDataOptionsUrl":"URL de servicio", "casSrvMetaDataOptionsUrl":"URL de servicio",
"casSrvName":"Nombre de servidor CAS", "casSrvName":"Nombre de servidor CAS",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Max age", "oidcOPMetaDataOptionsMaxAge":"Max age",
"oidcOPMetaDataOptionsPrompt":"Prompt", "oidcOPMetaDataOptionsPrompt":"Prompt",
"oidcOPMetaDataOptionsProtocol":"Protocolo", "oidcOPMetaDataOptionsProtocol":"Protocolo",
"oidcOPMetaDataOptionsResolutionRule":"Resolution rule",
"oidcOPMetaDataOptionsScope":"Ámbito", "oidcOPMetaDataOptionsScope":"Ámbito",
"oidcOPMetaDataOptionsSortNumber":"Orden", "oidcOPMetaDataOptionsSortNumber":"Orden",
"oidcOPMetaDataOptionsStoreIDToken":"Guardar token ID", "oidcOPMetaDataOptionsStoreIDToken":"Guardar token ID",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"Chemin de l'icône", "casSrvMetaDataOptionsIcon":"Chemin de l'icône",
"casSrvMetaDataOptionsProxiedServices":"Services mandatés", "casSrvMetaDataOptionsProxiedServices":"Services mandatés",
"casSrvMetaDataOptionsRenew":"Renouveler l'authentification", "casSrvMetaDataOptionsRenew":"Renouveler l'authentification",
"casSrvMetaDataOptionsResolutionRule":"Règle de résolution",
"casSrvMetaDataOptionsSortNumber":"Ordre", "casSrvMetaDataOptionsSortNumber":"Ordre",
"casSrvMetaDataOptionsUrl":"URL du serveur", "casSrvMetaDataOptionsUrl":"URL du serveur",
"casSrvName":"Nom du serveur CAS", "casSrvName":"Nom du serveur CAS",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Age maximum", "oidcOPMetaDataOptionsMaxAge":"Age maximum",
"oidcOPMetaDataOptionsPrompt":"Interaction", "oidcOPMetaDataOptionsPrompt":"Interaction",
"oidcOPMetaDataOptionsProtocol":"Protocole", "oidcOPMetaDataOptionsProtocol":"Protocole",
"oidcOPMetaDataOptionsResolutionRule":"Règle de résolution",
"oidcOPMetaDataOptionsScope":"Scope", "oidcOPMetaDataOptionsScope":"Scope",
"oidcOPMetaDataOptionsSortNumber":"Ordre", "oidcOPMetaDataOptionsSortNumber":"Ordre",
"oidcOPMetaDataOptionsStoreIDToken":"Conserver le jeton d'identité", "oidcOPMetaDataOptionsStoreIDToken":"Conserver le jeton d'identité",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"נתיב לסמל", "casSrvMetaDataOptionsIcon":"נתיב לסמל",
"casSrvMetaDataOptionsProxiedServices":"שירותים מתווכים", "casSrvMetaDataOptionsProxiedServices":"שירותים מתווכים",
"casSrvMetaDataOptionsRenew":"חידוש אימות", "casSrvMetaDataOptionsRenew":"חידוש אימות",
"casSrvMetaDataOptionsResolutionRule":"Resolution rule",
"casSrvMetaDataOptionsSortNumber":"סדר", "casSrvMetaDataOptionsSortNumber":"סדר",
"casSrvMetaDataOptionsUrl":"כתובת שרת", "casSrvMetaDataOptionsUrl":"כתובת שרת",
"casSrvName":"CAS Server Name", "casSrvName":"CAS Server Name",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"גיל מרבי", "oidcOPMetaDataOptionsMaxAge":"גיל מרבי",
"oidcOPMetaDataOptionsPrompt":"Prompt", "oidcOPMetaDataOptionsPrompt":"Prompt",
"oidcOPMetaDataOptionsProtocol":"פרוטוקול", "oidcOPMetaDataOptionsProtocol":"פרוטוקול",
"oidcOPMetaDataOptionsResolutionRule":"Resolution rule",
"oidcOPMetaDataOptionsScope":"היקף", "oidcOPMetaDataOptionsScope":"היקף",
"oidcOPMetaDataOptionsSortNumber":"סדר", "oidcOPMetaDataOptionsSortNumber":"סדר",
"oidcOPMetaDataOptionsStoreIDToken":"Store ID Token", "oidcOPMetaDataOptionsStoreIDToken":"Store ID Token",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"Path icona", "casSrvMetaDataOptionsIcon":"Path icona",
"casSrvMetaDataOptionsProxiedServices":"Servizi Proxied", "casSrvMetaDataOptionsProxiedServices":"Servizi Proxied",
"casSrvMetaDataOptionsRenew":"Rinnova l'autenticazione", "casSrvMetaDataOptionsRenew":"Rinnova l'autenticazione",
"casSrvMetaDataOptionsResolutionRule":"Regola di risoluzione",
"casSrvMetaDataOptionsSortNumber":"Ordine", "casSrvMetaDataOptionsSortNumber":"Ordine",
"casSrvMetaDataOptionsUrl":"URL del server", "casSrvMetaDataOptionsUrl":"URL del server",
"casSrvName":"NOme del Server CAS", "casSrvName":"NOme del Server CAS",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Età massima", "oidcOPMetaDataOptionsMaxAge":"Età massima",
"oidcOPMetaDataOptionsPrompt":"Richiesta", "oidcOPMetaDataOptionsPrompt":"Richiesta",
"oidcOPMetaDataOptionsProtocol":"Protocollo", "oidcOPMetaDataOptionsProtocol":"Protocollo",
"oidcOPMetaDataOptionsResolutionRule":"Regola di risoluzione",
"oidcOPMetaDataOptionsScope":"Scopo", "oidcOPMetaDataOptionsScope":"Scopo",
"oidcOPMetaDataOptionsSortNumber":"Ordine", "oidcOPMetaDataOptionsSortNumber":"Ordine",
"oidcOPMetaDataOptionsStoreIDToken":"Immagazzina ID Token", "oidcOPMetaDataOptionsStoreIDToken":"Immagazzina ID Token",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"Ścieżka ikony", "casSrvMetaDataOptionsIcon":"Ścieżka ikony",
"casSrvMetaDataOptionsProxiedServices":"Usługi proxy", "casSrvMetaDataOptionsProxiedServices":"Usługi proxy",
"casSrvMetaDataOptionsRenew":"Odnów uwierzytelnianie", "casSrvMetaDataOptionsRenew":"Odnów uwierzytelnianie",
"casSrvMetaDataOptionsResolutionRule":"Reguła rozstrzygania",
"casSrvMetaDataOptionsSortNumber":"Kolejność", "casSrvMetaDataOptionsSortNumber":"Kolejność",
"casSrvMetaDataOptionsUrl":"URL serwera", "casSrvMetaDataOptionsUrl":"URL serwera",
"casSrvName":"Nazwa serwera CAS", "casSrvName":"Nazwa serwera CAS",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Maksymalny czas ważności", "oidcOPMetaDataOptionsMaxAge":"Maksymalny czas ważności",
"oidcOPMetaDataOptionsPrompt":"Prompt", "oidcOPMetaDataOptionsPrompt":"Prompt",
"oidcOPMetaDataOptionsProtocol":"Protokół", "oidcOPMetaDataOptionsProtocol":"Protokół",
"oidcOPMetaDataOptionsResolutionRule":"Reguła rozstrzygania",
"oidcOPMetaDataOptionsScope":"Zakres", "oidcOPMetaDataOptionsScope":"Zakres",
"oidcOPMetaDataOptionsSortNumber":"Kolejność", "oidcOPMetaDataOptionsSortNumber":"Kolejność",
"oidcOPMetaDataOptionsStoreIDToken":"Przechowuj token identyfikacyjny", "oidcOPMetaDataOptionsStoreIDToken":"Przechowuj token identyfikacyjny",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"İkon yolu", "casSrvMetaDataOptionsIcon":"İkon yolu",
"casSrvMetaDataOptionsProxiedServices":"Vekil sunucu servisleri", "casSrvMetaDataOptionsProxiedServices":"Vekil sunucu servisleri",
"casSrvMetaDataOptionsRenew":"Kimlik doğrulamayı yenile", "casSrvMetaDataOptionsRenew":"Kimlik doğrulamayı yenile",
"casSrvMetaDataOptionsResolutionRule":"Çözünürlük kuralı",
"casSrvMetaDataOptionsSortNumber":"Sıra", "casSrvMetaDataOptionsSortNumber":"Sıra",
"casSrvMetaDataOptionsUrl":"Sunucu URL'si", "casSrvMetaDataOptionsUrl":"Sunucu URL'si",
"casSrvName":"CAS Sunucu Adı", "casSrvName":"CAS Sunucu Adı",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Maksimum ömür", "oidcOPMetaDataOptionsMaxAge":"Maksimum ömür",
"oidcOPMetaDataOptionsPrompt":"İstem", "oidcOPMetaDataOptionsPrompt":"İstem",
"oidcOPMetaDataOptionsProtocol":"Protokol", "oidcOPMetaDataOptionsProtocol":"Protokol",
"oidcOPMetaDataOptionsResolutionRule":"Çözünürlük kuralı",
"oidcOPMetaDataOptionsScope":"Kapsam", "oidcOPMetaDataOptionsScope":"Kapsam",
"oidcOPMetaDataOptionsSortNumber":"Sıra", "oidcOPMetaDataOptionsSortNumber":"Sıra",
"oidcOPMetaDataOptionsStoreIDToken":"ID Jetonu Sakla", "oidcOPMetaDataOptionsStoreIDToken":"ID Jetonu Sakla",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"Đường dẫn Icon", "casSrvMetaDataOptionsIcon":"Đường dẫn Icon",
"casSrvMetaDataOptionsProxiedServices":"Dịch vụ proxy", "casSrvMetaDataOptionsProxiedServices":"Dịch vụ proxy",
"casSrvMetaDataOptionsRenew":"Gia hạn chứng thực", "casSrvMetaDataOptionsRenew":"Gia hạn chứng thực",
"casSrvMetaDataOptionsResolutionRule":"Quy tắc phân giải ",
"casSrvMetaDataOptionsSortNumber":"Order", "casSrvMetaDataOptionsSortNumber":"Order",
"casSrvMetaDataOptionsUrl":"URL máy chủ", "casSrvMetaDataOptionsUrl":"URL máy chủ",
"casSrvName":"Tên máy chủ CAS", "casSrvName":"Tên máy chủ CAS",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"Thời hạn tối đa", "oidcOPMetaDataOptionsMaxAge":"Thời hạn tối đa",
"oidcOPMetaDataOptionsPrompt":"Nhắc nhở", "oidcOPMetaDataOptionsPrompt":"Nhắc nhở",
"oidcOPMetaDataOptionsProtocol":"Giao thức", "oidcOPMetaDataOptionsProtocol":"Giao thức",
"oidcOPMetaDataOptionsResolutionRule":"Quy tắc phân giải ",
"oidcOPMetaDataOptionsScope":"Phạm vi", "oidcOPMetaDataOptionsScope":"Phạm vi",
"oidcOPMetaDataOptionsSortNumber":"Order", "oidcOPMetaDataOptionsSortNumber":"Order",
"oidcOPMetaDataOptionsStoreIDToken":"Mã thông báo Cửa hàng", "oidcOPMetaDataOptionsStoreIDToken":"Mã thông báo Cửa hàng",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"图标路径", "casSrvMetaDataOptionsIcon":"图标路径",
"casSrvMetaDataOptionsProxiedServices":"代理服务", "casSrvMetaDataOptionsProxiedServices":"代理服务",
"casSrvMetaDataOptionsRenew":"更新驗證", "casSrvMetaDataOptionsRenew":"更新驗證",
"casSrvMetaDataOptionsResolutionRule":"解析規則",
"casSrvMetaDataOptionsSortNumber":"順序", "casSrvMetaDataOptionsSortNumber":"順序",
"casSrvMetaDataOptionsUrl":"服务器 URL", "casSrvMetaDataOptionsUrl":"服务器 URL",
"casSrvName":"CAS 服务器名称", "casSrvName":"CAS 服务器名称",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"最大時間", "oidcOPMetaDataOptionsMaxAge":"最大時間",
"oidcOPMetaDataOptionsPrompt":"提示", "oidcOPMetaDataOptionsPrompt":"提示",
"oidcOPMetaDataOptionsProtocol":"協定", "oidcOPMetaDataOptionsProtocol":"協定",
"oidcOPMetaDataOptionsResolutionRule":"解析規則",
"oidcOPMetaDataOptionsScope":"範圍", "oidcOPMetaDataOptionsScope":"範圍",
"oidcOPMetaDataOptionsSortNumber":"順序", "oidcOPMetaDataOptionsSortNumber":"順序",
"oidcOPMetaDataOptionsStoreIDToken":"儲存 ID 權杖", "oidcOPMetaDataOptionsStoreIDToken":"儲存 ID 權杖",

View File

@ -161,6 +161,7 @@
"casSrvMetaDataOptionsIcon":"圖示路徑", "casSrvMetaDataOptionsIcon":"圖示路徑",
"casSrvMetaDataOptionsProxiedServices":"已代理的服務", "casSrvMetaDataOptionsProxiedServices":"已代理的服務",
"casSrvMetaDataOptionsRenew":"更新驗證", "casSrvMetaDataOptionsRenew":"更新驗證",
"casSrvMetaDataOptionsResolutionRule":"解析規則",
"casSrvMetaDataOptionsSortNumber":"順序", "casSrvMetaDataOptionsSortNumber":"順序",
"casSrvMetaDataOptionsUrl":"伺服器 URL", "casSrvMetaDataOptionsUrl":"伺服器 URL",
"casSrvName":"CAS 伺服器名稱", "casSrvName":"CAS 伺服器名稱",
@ -652,6 +653,7 @@
"oidcOPMetaDataOptionsMaxAge":"最大時間", "oidcOPMetaDataOptionsMaxAge":"最大時間",
"oidcOPMetaDataOptionsPrompt":"提示", "oidcOPMetaDataOptionsPrompt":"提示",
"oidcOPMetaDataOptionsProtocol":"協定", "oidcOPMetaDataOptionsProtocol":"協定",
"oidcOPMetaDataOptionsResolutionRule":"解析規則",
"oidcOPMetaDataOptionsScope":"範圍", "oidcOPMetaDataOptionsScope":"範圍",
"oidcOPMetaDataOptionsSortNumber":"順序", "oidcOPMetaDataOptionsSortNumber":"順序",
"oidcOPMetaDataOptionsStoreIDToken":"儲存 ID 權杖", "oidcOPMetaDataOptionsStoreIDToken":"儲存 ID 權杖",

View File

@ -561,8 +561,9 @@ t/30-Auth-and-issuer-SAML-POST.t
t/30-Auth-and-issuer-SAML-Redirect-IdP-initiated.t t/30-Auth-and-issuer-SAML-Redirect-IdP-initiated.t
t/30-Auth-and-issuer-SAML-Redirect-MultipleSP-Missing-SLO.t t/30-Auth-and-issuer-SAML-Redirect-MultipleSP-Missing-SLO.t
t/30-Auth-and-issuer-SAML-Redirect-MultipleSP.t t/30-Auth-and-issuer-SAML-Redirect-MultipleSP.t
t/30-Auth-and-issuer-SAML-Redirect-With-Info.t
t/30-Auth-and-issuer-SAML-Redirect.t t/30-Auth-and-issuer-SAML-Redirect.t
t/30-Auth-and-issuer-SAML-Redirect-With-Info.t
t/30-Auth-ResolutionRule.t
t/30-Auth-SAML-with-choice.t t/30-Auth-SAML-with-choice.t
t/30-CDC.t t/30-CDC.t
t/30-SAML-Head-to-Tail-POST.t t/30-SAML-Head-to-Tail-POST.t

View File

@ -133,16 +133,26 @@ sub extractFormInfo {
else { else {
# Try to use server resolution ruls
foreach ( keys %{ $self->srvRules } ) {
my $cond = $self->srvRules->{$_} or next;
if ( $cond->( $req, $req->sessionInfo ) ) {
$self->logger->debug(
"CAS Server $_ selected from resolution rule");
$srv = $_;
last;
}
}
unless ($srv) {
# Server list # Server list
my $portalPath = $self->conf->{portal};
$portalPath =~ s#^https?://[^/]+/?#/#;
$req->data->{list} = $self->srvList; $req->data->{list} = $self->srvList;
$req->data->{login} = 1; $req->data->{login} = 1;
return PE_IDPCHOICE; return PE_IDPCHOICE;
} }
} }
}
my $srvConf = $self->conf->{casSrvMetaDataOptions}->{$srv}; my $srvConf = $self->conf->{casSrvMetaDataOptions}->{$srv};
unless ($srvConf) { unless ($srvConf) {

View File

@ -249,16 +249,25 @@ sub extractFormInfo {
else { else {
# IDP list # Try to use OP resolution ruls
my $portalPath = $self->{conf}->{portal}; foreach ( keys %{ $self->opRules } ) {
$portalPath =~ s#^https?://[^/]+/?#/#; my $cond = $self->opRules->{$_} or next;
if ( $cond->( $req, $req->sessionInfo ) ) {
$self->logger->debug("OP $_ selected from resolution rule");
$op = $_;
last;
}
}
unless ($op) {
# display OP list
$req->data->{list} = $self->opList; $req->data->{list} = $self->opList;
$req->data->{login} = 1; $req->data->{login} = 1;
return PE_IDPCHOICE; return PE_IDPCHOICE;
} }
} }
}
# Provider is choosen # Provider is choosen
$self->logger->debug("OpenID Provider $op choosen"); $self->logger->debug("OpenID Provider $op choosen");

View File

@ -26,6 +26,7 @@ has ua => (
has casSrvList => ( is => 'rw', default => sub { {} }, ); has casSrvList => ( is => 'rw', default => sub { {} }, );
has casAppList => ( is => 'rw', default => sub { {} }, ); has casAppList => ( is => 'rw', default => sub { {} }, );
has srvRules => ( is => 'rw', default => sub { {} }, );
has spRules => ( is => 'rw', default => sub { {} }, ); has spRules => ( is => 'rw', default => sub { {} }, );
has spMacros => ( is => 'rw', default => sub { {} }, ); has spMacros => ( is => 'rw', default => sub { {} }, );
@ -41,6 +42,18 @@ sub loadSrv {
return 0; return 0;
} }
$self->casSrvList( $self->conf->{casSrvMetaDataOptions} ); $self->casSrvList( $self->conf->{casSrvMetaDataOptions} );
# Set rule
foreach ( keys %{ $self->conf->{casSrvMetaDataOptions} } ) {
my $cond = $self->conf->{casSrvMetaDataOptions}->{$_}
->{casSrvMetaDataOptionsResolutionRule};
if ( length $cond ) {
my $rule_sub = $self->p->buildRule( $cond, "CAS server resolution" );
if ($rule_sub) {
$self->srvRules->{$_} = $rule_sub;
}
}
}
return 1; return 1;
} }

View File

@ -41,6 +41,7 @@ use constant OIDC_SCOPES => [qw/openid profile email address phone/];
has oidcOPList => ( is => 'rw', default => sub { {} }, ); has oidcOPList => ( is => 'rw', default => sub { {} }, );
has oidcRPList => ( is => 'rw', default => sub { {} }, ); has oidcRPList => ( is => 'rw', default => sub { {} }, );
has rpAttributes => ( is => 'rw', default => sub { {} }, ); has rpAttributes => ( is => 'rw', default => sub { {} }, );
has opRules => ( is => 'rw', default => sub { {} } );
has spRules => ( is => 'rw', default => sub { {} } ); has spRules => ( is => 'rw', default => sub { {} } );
has spMacros => ( is => 'rw', default => sub { {} } ); has spMacros => ( is => 'rw', default => sub { {} } );
has spScopeRules => ( is => 'rw', default => sub { {} } ); has spScopeRules => ( is => 'rw', default => sub { {} } );
@ -90,6 +91,20 @@ sub loadOPs {
$self->oidcOPList->{$_}->{jwks} = $self->oidcOPList->{$_}->{jwks} =
$self->decodeJSON( $self->conf->{oidcOPMetaDataJWKS}->{$_} ); $self->decodeJSON( $self->conf->{oidcOPMetaDataJWKS}->{$_} );
} }
# Set rule
foreach ( keys %{ $self->conf->{oidcOPMetaDataOptions} } ) {
my $cond = $self->conf->{oidcOPMetaDataOptions}->{$_}
->{oidcOPMetaDataOptionsResolutionRule};
if ( length $cond ) {
my $rule_sub =
$self->p->buildRule( $cond, "OIDC provider resolution" );
if ($rule_sub) {
$self->opRules->{$_} = $rule_sub;
}
}
}
return 1; return 1;
} }

View File

@ -0,0 +1,138 @@
use lib 'inc';
use Test::More;
use strict;
use IO::String;
use LWP::UserAgent;
use LWP::Protocol::PSGI;
use MIME::Base64;
use XML::LibXML;
BEGIN {
require 't/test-lib.pm';
require 't/saml-lib.pm';
}
my $debug = 'error';
my ( $issuer, $res );
my $maintests = 0;
sub testchoiceredirection {
my ( $issuer, $choice, $url ) = @_;
my $res;
ok(
$res = $issuer->_get(
'/',
query => 'lmAuth=' . $choice,
accept => 'text/html',
),
'Auth query'
);
count(1);
expectRedirection( $res, $url );
}
SKIP: {
eval "use Lasso";
if ($@) {
skip 'Lasso not found', $maintests;
}
# Initialization
ok( $issuer = issuer(), 'Issuer portal' );
count(1);
testchoiceredirection( $issuer, 'SAML1',
qr,http://auth.idp.com/saml/singleSignOn, );
testchoiceredirection( $issuer, 'SAML2',
qr,http://auth.idp2.com/saml/singleSignOn, );
testchoiceredirection( $issuer, 'OIDC1',
qr,http://auth.op.com/oauth2/authorize, );
testchoiceredirection( $issuer, 'OIDC2',
qr,http://auth.op2.com/oauth2/authorize, );
testchoiceredirection( $issuer, 'CAS1', qr,http://auth.srv.com/cas/login, );
testchoiceredirection( $issuer, 'CAS2',
qr,http://auth.srv2.com/cas/login, );
clean_sessions();
}
count($maintests);
done_testing( count() );
sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'example.com',
portal => 'http://auth.example.com',
authentication => 'Choice',
userDB => 'Same',
authChoiceModules => {
'OIDC1' => 'OpenIDConnect;Null;Null',
'OIDC2' => 'OpenIDConnect;Null;Null',
'SAML1' => 'SAML;Null;Null',
'SAML2' => 'SAML;Null;Null',
'CAS1' => 'CAS;Null;Null',
'CAS2' => 'CAS;Null;Null',
},
samlIDPMetaDataOptions => {
"idp.com" => {
samlIDPMetaDataOptionsResolutionRule =>
'$_choice eq "SAML1"',
},
"idp2.com" => {
samlIDPMetaDataOptionsResolutionRule =>
'$_choice eq "SAML2"',
},
},
samlIDPMetaDataXML => {
"idp.com" => {
samlIDPMetaDataXML =>
samlIDPMetaDataXML( 'idp', 'HTTP-Redirect' )
},
"idp2.com" => {
samlIDPMetaDataXML =>
samlIDPMetaDataXML( 'idp2', 'HTTP-Redirect' )
},
},
samlServicePrivateKeyEnc => saml_key_idp_private_enc,
samlServicePrivateKeySig => saml_key_idp_private_sig,
samlServicePublicKeyEnc => saml_key_idp_public_enc,
samlServicePublicKeySig => saml_key_idp_public_sig,
casSrvMetaDataOptions => {
idp => {
casSrvMetaDataOptionsUrl => 'http://auth.srv.com/cas',
casSrvMetaDataOptionsResolutionRule =>
'$_choice eq "CAS1"',
},
idp2 => {
casSrvMetaDataOptionsUrl => 'http://auth.srv2.com/cas',
casSrvMetaDataOptionsResolutionRule =>
'$_choice eq "CAS2"',
},
},
oidcOPMetaDataOptions => {
op => {
oidcOPMetaDataOptionsClientSecret => "rpsecret",
oidcOPMetaDataOptionsResolutionRule =>
'$_choice eq "OIDC1"',
},
op2 => {
oidcOPMetaDataOptionsResolutionRule =>
'$_choice eq "OIDC2"',
},
},
oidcOPMetaDataJSON => {
op =>
'{"authorization_endpoint":"http://auth.op.com/oauth2/authorize"}',
op2 =>
'{"authorization_endpoint":"http://auth.op2.com/oauth2/authorize"}',
}
}
}
);
}