@@ -34,6 +34,9 @@ class Disco extends PowerIdPDisco
3434 public const WAYF = 'wayf_config ' ;
3535 # CONFIGURATION ENTRIES
3636 public const BOXED = 'boxed ' ;
37+ public const TRANSLATE_MODULE = 'translate_module ' ;
38+ public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES = 'remove_authn_context_class_ref_prefixes ' ;
39+ public const DISABLE_WHITELISTING = 'disable_whitelisting ' ;
3740 # CONFIGURATION ENTRIES IDP BLOCKS
3841 public const IDP_BLOCKS = 'idp_blocks_config ' ;
3942 public const IDP_BLOCK_TYPE = 'type ' ;
@@ -50,9 +53,6 @@ class Disco extends PowerIdPDisco
5053 public const ADD_INSTITUTION = 'add_institution_config ' ;
5154 public const ADD_INSTITUTION_URL = 'url ' ;
5255 public const ADD_INSTITUTION_EMAIL = 'email ' ;
53- public const TRANSLATE_MODULE = 'translate_module ' ;
54- public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIX = 'remove_authn_context_class_ref_prefix ' ;
55- public const DISABLE_WHITELISTING = 'disable_whitelisting ' ;
5656
5757 # PARAMS AND DATA KEYS
5858 public const ENTITY_ID = "entityID " ;
@@ -84,12 +84,25 @@ class Disco extends PowerIdPDisco
8484 public const SAML_SP_SSO = 'saml:sp:sso ' ;
8585
8686 private $ originalsp ;
87- private array $ authnContextClassRef = [];
87+ private array $ originalAuthnContextClassRef = [];
88+ private $ wayfConfiguration ;
89+ private $ perunModuleConfiguration ;
90+
91+ private $ proxyIdpEntityId ;
8892
8993 public function __construct (
9094 array $ metadataSets ,
9195 $ instance
9296 ) {
97+ //LOAD CONFIG FOR MODULE PERUN, WHICH CONTAINS WAYF CONFIGURATION
98+ try {
99+ $ this ->perunModuleConfiguration = Configuration::getConfig (Disco::CONFIG_FILE_NAME );
100+ $ this ->wayfConfiguration = $ this ->perunModuleConfiguration ->getConfigItem (self ::WAYF );
101+ } catch (\Exception $ ex ) {
102+ Logger::error ("perun:disco-tpl: missing or invalid ' " . self ::CONFIG_FILE_NAME . "' config file " );
103+ throw $ ex ;
104+ }
105+
93106 if (!array_key_exists (self ::RETURN , $ _GET )) {
94107 throw new \Exception ('Missing parameter: ' . self ::RETURN );
95108 } else {
@@ -104,13 +117,13 @@ public function __construct(
104117
105118 if ($ state !== null ) {
106119 if (isset ($ state [self ::SAML_REQUESTED_AUTHN_CONTEXT ][self ::AUTHN_CONTEXT_CLASS_REF ])) {
107- $ this ->authnContextClassRef = $ state [self ::SAML_REQUESTED_AUTHN_CONTEXT ]
120+ $ this ->originalAuthnContextClassRef = $ state [self ::SAML_REQUESTED_AUTHN_CONTEXT ]
108121 [self ::AUTHN_CONTEXT_CLASS_REF ];
109- $ this ->removeAuthContextClassRefWithPrefix ($ state );
122+ $ this ->removeAuthContextClassRefWithPrefixes ($ state );
123+ if (isset ($ state ['IdPMetadata ' ]['entityid ' ])) {
124+ $ this ->proxyIdpEntityId = $ state ['IdPMetadata ' ]['entityid ' ];
125+ }
110126 }
111-
112- $ id = State::saveState ($ state , self ::SAML_SP_SSO );
113-
114127 $ e = explode ("= " , $ returnURL )[0 ];
115128 $ newReturnURL = $ e . "= " . urlencode ($ id );
116129 $ _GET [self ::RETURN ] = $ newReturnURL ;
@@ -143,9 +156,6 @@ public function handleRequest()
143156 } else {
144157 $ idpList = $ this ->filterList ($ idpList );
145158 }
146- $ preferredIdP = $ this ->getRecommendedIdP ();
147- $ preferredIdP = array_key_exists ($ preferredIdP , $ idpList )
148- ? $ preferredIdP : null ;
149159
150160 if (sizeof ($ idpList ) === 1 ) {
151161 $ idp = array_keys ($ idpList )[0 ];
@@ -160,15 +170,21 @@ public function handleRequest()
160170 HTTP ::redirectTrustedURL ($ url );
161171 }
162172
173+ $ preferredIdP = $ this ->getRecommendedIdP ();
174+ $ preferredIdP = array_key_exists ($ preferredIdP , $ idpList ) ? $ preferredIdP : null ;
175+
163176 // IF IS SET AUTHN CONTEXT CLASS REF, REDIRECT USER TO THE IDP
164- if (isset ($ this ->authnContextClassRef )) {
165- if ($ this ->authnContextClassRef !== null ) {
177+ if (isset ($ this ->originalAuthnContextClassRef )) {
178+ if ($ this ->originalAuthnContextClassRef !== null ) {
166179 # Check authnContextClassRef and select IdP directly if the correct value is set
167- foreach ($ this ->authnContextClassRef as $ value ) {
180+ foreach ($ this ->originalAuthnContextClassRef as $ value ) {
168181 // VERIFY THE PREFIX IS CORRECT AND WE CAN PERFORM THE REDIRECT
169182 $ acrStartSubstr = substr ($ value , 0 , strlen (Disco::URN_CESNET_PROXYIDP_IDPENTITYID ));
170183 if ($ acrStartSubstr === Disco::URN_CESNET_PROXYIDP_IDPENTITYID ) {
171184 $ idpEntityId = substr ($ value , strlen (Disco::URN_CESNET_PROXYIDP_IDPENTITYID ), strlen ($ value ));
185+ if ($ idpEntityId === $ this ->proxyIdpEntityId ) {
186+ continue ;
187+ }
172188 Logger::info ('Redirecting to ' . $ idpEntityId );
173189 $ url = Disco::buildContinueUrl (
174190 $ this ->spEntityId ,
@@ -182,15 +198,6 @@ public function handleRequest()
182198 }
183199 }
184200
185- //LOAD CONFIG FOR MODULE PERUN, WHICH CONTAINS WAYF CONFIGURATION
186- $ perunModuleConfig = null ;
187- try {
188- $ perunModuleConfig = Configuration::getConfig (Disco::CONFIG_FILE_NAME );
189- } catch (\Exception $ ex ) {
190- Logger::error ("perun:disco-tpl: missing or invalid ' " . self ::CONFIG_FILE_NAME . "' config file " );
191- throw $ ex ;
192- }
193-
194201 $ warningAttributes = null ;
195202 try {
196203 $ warningInstance = WarningConfiguration::getInstance ();
@@ -206,9 +213,9 @@ public function handleRequest()
206213 $ t ->data [self ::ENTITY_ID ] = $ this ->spEntityId ;
207214 $ t ->data [self ::RETURN ] = $ this ->returnURL ;
208215 $ t ->data [self ::RETURN_ID_PARAM ] = $ this ->returnIdParam ;
209- $ t ->data [self ::AUTHN_CONTEXT_CLASS_REF ] = $ this ->authnContextClassRef ;
216+ $ t ->data [self ::AUTHN_CONTEXT_CLASS_REF ] = $ this ->originalAuthnContextClassRef ;
210217 $ t ->data [self ::WARNING_ATTRIBUTES ] = $ warningAttributes ;
211- $ t ->data [self ::WAYF ] = $ perunModuleConfig -> getConfigItem ( self :: WAYF ) ;
218+ $ t ->data [self ::WAYF ] = $ this -> wayfConfiguration ;
212219 $ t ->show ();
213220 }
214221
@@ -221,8 +228,7 @@ public function handleRequest()
221228 */
222229 protected function filterList ($ list ): array
223230 {
224- $ conf = Configuration::getConfig (self ::CONFIG_FILE_NAME );
225- $ disableWhitelisting = $ conf ->getBoolean (self ::DISABLE_WHITELISTING , false );
231+ $ disableWhitelisting = $ this ->wayfConfiguration ->getBoolean (self ::DISABLE_WHITELISTING , false );
226232
227233 if (!isset ($ this ->originalsp [Disco::METADATA_DO_NOT_FILTER_IDPS ])
228234 || !$ this ->originalsp [Disco::METADATA_DO_NOT_FILTER_IDPS ]
@@ -441,24 +447,24 @@ public static function buildContinueUrlWithoutIdPEntityId(
441447 * @param $state
442448 * @throws \Exception
443449 */
444- public function removeAuthContextClassRefWithPrefix (&$ state )
450+ public function removeAuthContextClassRefWithPrefixes (&$ state )
445451 {
446- $ conf = Configuration::getConfig (self ::CONFIG_FILE_NAME );
447- $ prefix = $ conf ->getString (self ::REMOVE_AUTHN_CONTEXT_CLASS_PREFIX , null );
452+ $ prefixes = $ this ->wayfConfiguration ->getArray (self ::REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES , []);
448453
449- if ($ prefix === null ) {
454+ if (empty ( $ prefixes ) ) {
450455 return ;
451456 }
452457 unset($ state [self ::SAML_REQUESTED_AUTHN_CONTEXT ][self ::STATE_AUTHN_CONTEXT_CLASS_REF ]);
453- $ array = [];
454- foreach ($ this ->authnContextClassRef as $ value ) {
455- if (!(substr ($ value , 0 , strlen ($ prefix )) === $ prefix )) {
456- array_push ($ array , $ value );
458+ $ filteredAcrs = [];
459+ foreach ($ this ->originalAuthnContextClassRef as $ acr ) {
460+ foreach ($ prefixes as $ prefix ) {
461+ if (!(substr ($ acr , 0 , strlen ($ prefix )) === $ prefix )) {
462+ array_push ($ filteredAcrs , $ acr );
463+ }
457464 }
458465 }
459- if (!empty ($ array )) {
460- $ state [self ::SAML_REQUESTED_AUTHN_CONTEXT ][self ::STATE_AUTHN_CONTEXT_CLASS_REF ]
461- = $ array ;
466+ if (!empty ($ filteredAcrs )) {
467+ $ state [self ::SAML_REQUESTED_AUTHN_CONTEXT ][self ::STATE_AUTHN_CONTEXT_CLASS_REF ] = $ filteredAcrs ;
462468 }
463469 }
464470
0 commit comments