IdP no longer sends xerces type hack unless specified in the relying party configuration.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / common / ServiceProviderMapper.java
1 /*
2  * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation for Advanced Internet Development, Inc.
3  * All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted
4  * provided that the following conditions are met: Redistributions of source code must retain the above copyright
5  * notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above
6  * copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials
7  * provided with the distribution, if any, must include the following acknowledgment: "This product includes software
8  * developed by the University Corporation for Advanced Internet Development <http://www.ucaid.edu> Internet2 Project.
9  * Alternately, this acknowledegement may appear in the software itself, if and wherever such third-party
10  * acknowledgments normally appear. Neither the name of Shibboleth nor the names of its contributors, nor Internet2, nor
11  * the University Corporation for Advanced Internet Development, Inc., nor UCAID may be used to endorse or promote
12  * products derived from this software without specific prior written permission. For written permission, please contact
13  * shibboleth@shibboleth.org Products derived from this software may not be called Shibboleth, Internet2, UCAID, or the
14  * University Corporation for Advanced Internet Development, nor may Shibboleth appear in their name, without prior
15  * written permission of the University Corporation for Advanced Internet Development. THIS SOFTWARE IS PROVIDED BY THE
16  * COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE
18  * DISCLAIMED AND THE ENTIRE RISK OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. IN NO
19  * EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC.
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 package edu.internet2.middleware.shibboleth.common;
27
28 import java.net.MalformedURLException;
29 import java.net.URI;
30 import java.net.URISyntaxException;
31 import java.net.URL;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import org.apache.log4j.Logger;
36 import org.w3c.dom.Element;
37 import org.w3c.dom.NodeList;
38
39 import edu.internet2.middleware.shibboleth.idp.IdPConfig;
40 import edu.internet2.middleware.shibboleth.metadata.EntitiesDescriptor;
41 import edu.internet2.middleware.shibboleth.metadata.Metadata;
42 import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
43
44 /**
45  * Class for determining the effective relying party from the unique id of the service provider. Checks first for an
46  * exact match on the service provider, then for membership in a group of providers (perhaps a federation). Uses the
47  * default relying party if neither is found.
48  * 
49  * @author Walter Hoehn
50  */
51 public class ServiceProviderMapper {
52
53         private static Logger log = Logger.getLogger(ServiceProviderMapper.class.getName());
54         protected Map relyingParties = new HashMap();
55         private Metadata metaData;
56         private IdPConfig configuration;
57         private Credentials credentials;
58         private NameMapper nameMapper;
59
60         public ServiceProviderMapper(Element rawConfig, IdPConfig configuration, Credentials credentials,
61                         NameMapper nameMapper) throws ServiceProviderMapperException {
62
63                 this.configuration = configuration;
64                 this.credentials = credentials;
65                 this.nameMapper = nameMapper;
66
67                 NodeList itemElements = rawConfig.getElementsByTagNameNS(IdPConfig.configNameSpace, "RelyingParty");
68
69                 for (int i = 0; i < itemElements.getLength(); i++) {
70                         addRelyingParty((Element) itemElements.item(i));
71                 }
72
73                 verifyDefaultParty(configuration);
74
75         }
76
77         public void setMetadata(Metadata metadata) {
78
79                 this.metaData = metadata;
80         }
81
82         private IdPConfig getOriginConfig() {
83
84                 return configuration;
85         }
86
87         protected void verifyDefaultParty(IdPConfig configuration) throws ServiceProviderMapperException {
88
89                 // Verify we have a proper default party
90                 String defaultParty = configuration.getDefaultRelyingPartyName();
91                 if (defaultParty == null || defaultParty.equals("")) {
92                         if (relyingParties.size() != 1) {
93                                 log
94                                                 .error("Default Relying Party not specified.  Add a (defaultRelyingParty) attribute to <IdPConfig>.");
95                                 throw new ServiceProviderMapperException("Required configuration not specified.");
96                         } else {
97                                 log.debug("Only one Relying Party loaded.  Using this as the default.");
98                         }
99                 }
100                 log.debug("Default Relying Party set to: (" + defaultParty + ").");
101                 if (!relyingParties.containsKey(defaultParty)) {
102                         log.error("Default Relying Party refers to a Relying Party that has not been loaded.");
103                         throw new ServiceProviderMapperException("Invalid configuration (Default Relying Party).");
104                 }
105         }
106
107         protected RelyingParty getRelyingPartyImpl(String providerIdFromTarget) {
108
109                 // Null request, send the default
110                 if (providerIdFromTarget == null) {
111                         RelyingParty relyingParty = getDefaultRelyingParty();
112                         log.info("Using default Relying Party: (" + relyingParty.getName() + ").");
113                         return new UnknownProviderWrapper(relyingParty, providerIdFromTarget);
114                 }
115
116                 // Look for a configuration for the specific relying party
117                 if (relyingParties.containsKey(providerIdFromTarget)) {
118                         log.info("Found Relying Party for (" + providerIdFromTarget + ").");
119                         return (RelyingParty) relyingParties.get(providerIdFromTarget);
120                 }
121
122                 // Next, check to see if the relying party is in any groups
123                 RelyingParty groupParty = findRelyingPartyByGroup(providerIdFromTarget);
124                 if (groupParty != null) {
125                         log.info("Provider is a member of Relying Party (" + groupParty.getName() + ").");
126                         return new RelyingPartyGroupWrapper(groupParty, providerIdFromTarget);
127                 }
128
129                 // OK, we can't find it... just send the default
130                 RelyingParty relyingParty = getDefaultRelyingParty();
131                 log.info("Could not locate Relying Party configuration for (" + providerIdFromTarget
132                                 + ").  Using default Relying Party: (" + relyingParty.getName() + ").");
133                 return new UnknownProviderWrapper(relyingParty, providerIdFromTarget);
134         }
135
136         private RelyingParty findRelyingPartyByGroup(String providerIdFromTarget) {
137
138                 if (metaData == null) { return null; }
139
140                 EntityDescriptor provider = metaData.lookup(providerIdFromTarget);
141                 if (provider != null) {
142                         EntitiesDescriptor parent = provider.getEntitiesDescriptor();
143                         while (parent != null) {
144                                 if (relyingParties.containsKey(parent.getName())) {
145                                         log.info("Found matching Relying Party for group (" + parent.getName() + ").");
146                                         return (RelyingParty) relyingParties.get(parent.getName());
147                                 } else {
148                                         log.debug("Provider is a member of group (" + parent.getName()
149                                                         + "), but no matching Relying Party was found.");
150                                 }
151                                 parent = parent.getEntitiesDescriptor();
152                         }
153                 }
154                 return null;
155         }
156
157         public RelyingParty getDefaultRelyingParty() {
158
159                 // If there is no explicit default, pick the single configured Relying
160                 // Party
161                 String defaultParty = getOriginConfig().getDefaultRelyingPartyName();
162                 if (defaultParty == null || defaultParty.equals("")) { return (RelyingParty) relyingParties.values().iterator()
163                                 .next(); }
164
165                 // If we do have a default specified, use it...
166                 return (RelyingParty) relyingParties.get(defaultParty);
167         }
168
169         /**
170          * Returns the relying party for a legacy provider(the default)
171          */
172         public RelyingParty getLegacyRelyingParty() {
173
174                 RelyingParty relyingParty = getDefaultRelyingParty();
175                 log.info("Request is from legacy shib target.  Selecting default Relying Party: (" + relyingParty.getName()
176                                 + ").");
177                 return new LegacyWrapper((RelyingParty) relyingParty);
178
179         }
180
181         /**
182          * Returns the appropriate relying party for the supplied service provider id.
183          */
184         public RelyingParty getRelyingParty(String providerIdFromTarget) {
185
186                 if (providerIdFromTarget == null || providerIdFromTarget.equals("")) {
187                         RelyingParty relyingParty = getDefaultRelyingParty();
188                         log.info("Selecting default Relying Party: (" + relyingParty.getName() + ").");
189                         return new NoMetadataWrapper((RelyingParty) relyingParty);
190                 }
191
192                 return (RelyingParty) getRelyingPartyImpl(providerIdFromTarget);
193         }
194
195         private void addRelyingParty(Element e) throws ServiceProviderMapperException {
196
197                 log.debug("Found a Relying Party.");
198                 try {
199                         if (e.getLocalName().equals("RelyingParty")) {
200                                 RelyingParty party = new RelyingPartyImpl(e, configuration, credentials, nameMapper);
201                                 log.debug("Relying Party (" + party.getName() + ") loaded.");
202                                 relyingParties.put(party.getName(), party);
203                         }
204                 } catch (ServiceProviderMapperException exc) {
205                         log.error("Encountered an error while attempting to load Relying Party configuration.  Skipping...");
206                 }
207
208         }
209
210         /**
211          * Base relying party implementation.
212          * 
213          * @author Walter Hoehn
214          */
215         protected class RelyingPartyImpl implements RelyingParty {
216
217                 private RelyingPartyIdentityProvider identityProvider;
218                 private String name;
219                 private String overridenOriginProviderId;
220                 private URL overridenAAUrl;
221                 private URI overridenDefaultAuthMethod;
222                 private String hsNameFormatId;
223                 private IdPConfig configuration;
224                 private boolean overridenPassThruErrors = false;
225                 private boolean passThruIsOverriden = false;
226                 private boolean forceAttributePush = false;
227                 private boolean forceAttributeNoPush = false;
228                 private boolean defaultToPOST = true;
229                 private boolean wantsAssertionsSigned = false;
230                 private int preferredArtifactType = 1;
231                 private String defaultTarget;
232                 private boolean wantsSchemaHack = false;
233
234                 public RelyingPartyImpl(Element partyConfig, IdPConfig globalConfig, Credentials credentials,
235                                 NameMapper nameMapper) throws ServiceProviderMapperException {
236
237                         configuration = globalConfig;
238
239                         // Get party name
240                         name = ((Element) partyConfig).getAttribute("name");
241                         if (name == null || name.equals("")) {
242                                 log.error("Relying Party name not set.  Add a (name) attribute to <RelyingParty>.");
243                                 throw new ServiceProviderMapperException("Required configuration not specified.");
244                         }
245                         log.debug("Loading Relying Party: (" + name + ").");
246
247                         // Process overrides for global configuration data
248                         String attribute = ((Element) partyConfig).getAttribute("providerId");
249                         if (attribute != null && !attribute.equals("")) {
250                                 log.debug("Overriding providerId for Relying Pary (" + name + ") with (" + attribute + ").");
251                                 overridenOriginProviderId = attribute;
252                         }
253
254                         attribute = ((Element) partyConfig).getAttribute("AAUrl");
255                         if (attribute != null && !attribute.equals("")) {
256                                 log.debug("Overriding AAUrl for Relying Pary (" + name + ") with (" + attribute + ").");
257                                 try {
258                                         overridenAAUrl = new URL(attribute);
259                                 } catch (MalformedURLException e) {
260                                         log.error("(AAUrl) attribute to is not a valid URL.");
261                                         throw new ServiceProviderMapperException("Configuration is invalid.");
262                                 }
263                         }
264
265                         attribute = ((Element) partyConfig).getAttribute("defaultAuthMethod");
266                         if (attribute != null && !attribute.equals("")) {
267                                 log.debug("Overriding defaultAuthMethod for Relying Pary (" + name + ") with (" + attribute + ").");
268                                 try {
269                                         overridenDefaultAuthMethod = new URI(attribute);
270                                 } catch (URISyntaxException e1) {
271                                         log.error("(defaultAuthMethod) attribute to is not a valid URI.");
272                                         throw new ServiceProviderMapperException("Configuration is invalid.");
273                                 }
274                         }
275
276                         attribute = ((Element) partyConfig).getAttribute("passThruErrors");
277                         if (attribute != null && !attribute.equals("")) {
278                                 log.debug("Overriding passThruErrors for Relying Pary (" + name + ") with (" + attribute + ").");
279                                 overridenPassThruErrors = Boolean.valueOf(attribute).booleanValue();
280                                 passThruIsOverriden = true;
281                         }
282
283                         // SSO profile defaulting
284                         attribute = ((Element) partyConfig).getAttribute("defaultToPOSTProfile");
285                         if (attribute != null && !attribute.equals("")) {
286                                 defaultToPOST = Boolean.valueOf(attribute).booleanValue();
287                         }
288                         if (defaultToPOST) {
289                                 log.debug("Relying party defaults to POST profile.");
290                         } else {
291                                 log.debug("Relying party defaults to Artifact profile.");
292                         }
293
294                         // Relying Party wants assertions signed?
295                         attribute = ((Element) partyConfig).getAttribute("signAssertions");
296                         if (attribute != null && !attribute.equals("")) {
297                                 wantsAssertionsSigned = Boolean.valueOf(attribute).booleanValue();
298                         }
299                         if (wantsAssertionsSigned) {
300                                 log.debug("Relying party wants SAML Assertions to be signed.");
301                         } else {
302                                 log.debug("Relying party does not want SAML Assertions to be signed.");
303                         }
304
305                         // Decide whether or not to use the schema hack for old xerces
306                         attribute = ((Element) partyConfig).getAttribute("schemaHack");
307                         if (attribute != null && !attribute.equals("")) {
308                                 wantsSchemaHack = Boolean.valueOf(attribute).booleanValue();
309                         }
310                         if (wantsSchemaHack) {
311                                 log.debug("XML schema hack enabled for this relying party.");
312                         }
313
314                         // Set a default target for use in artifact redirects
315                         defaultTarget = ((Element) partyConfig).getAttribute("defaultTarget");
316
317                         // Determine whether or not we are forcing attribute push on or off
318                         String forcePush = ((Element) partyConfig).getAttribute("forceAttributePush");
319                         String forceNoPush = ((Element) partyConfig).getAttribute("forceAttributeNoPush");
320
321                         if (forcePush != null && Boolean.valueOf(forcePush).booleanValue() && forceNoPush != null
322                                         && Boolean.valueOf(forceNoPush).booleanValue()) {
323                                 log.error("Invalid configuration:  Attribute push is forced to ON and OFF for this relying "
324                                                 + "party.  Turning off forcing in favor of profile defaults.");
325                         } else {
326                                 forceAttributePush = Boolean.valueOf(forcePush).booleanValue();
327                                 forceAttributeNoPush = Boolean.valueOf(forceNoPush).booleanValue();
328                                 log.debug("Attribute push forcing is set to (" + forceAttributePush + ").");
329                                 log.debug("No attribute push forcing is set to (" + forceAttributeNoPush + ").");
330                         }
331
332                         attribute = ((Element) partyConfig).getAttribute("preferredArtifactType");
333                         if (attribute != null && !attribute.equals("")) {
334                                 log.debug("Overriding AAUrl for Relying Pary (" + name + ") with (" + attribute + ").");
335                                 try {
336                                         preferredArtifactType = Integer.parseInt(attribute);
337                                 } catch (NumberFormatException e) {
338                                         log.error("(preferredArtifactType) attribute to is not a valid integer.");
339                                         throw new ServiceProviderMapperException("Configuration is invalid.");
340                                 }
341                                 log.debug("Preferred artifact type: (" + preferredArtifactType + ").");
342                         }
343
344                         // Load and verify the name format that the HS should use in
345                         // assertions for this RelyingParty
346                         NodeList hsNameFormats = ((Element) partyConfig).getElementsByTagNameNS(IdPConfig.configNameSpace,
347                                         "HSNameFormat");
348                         // If no specification. Make sure we have a default mapping
349                         if (hsNameFormats.getLength() < 1) {
350                                 if (nameMapper.getNameIdentifierMappingById(null) == null) {
351                                         log.error("Relying Party HS Name Format not set.  Add a <HSNameFormat> element to <RelyingParty>.");
352                                         throw new ServiceProviderMapperException("Required configuration not specified.");
353                                 }
354
355                         } else {
356                                 // We do have a specification, so make sure it points to a
357                                 // valid Name Mapping
358                                 if (hsNameFormats.getLength() > 1) {
359                                         log.warn("Found multiple HSNameFormat specifications for Relying Party (" + name
360                                                         + ").  Ignoring all but the first.");
361                                 }
362
363                                 hsNameFormatId = ((Element) hsNameFormats.item(0)).getAttribute("nameMapping");
364                                 if (hsNameFormatId == null || hsNameFormatId.equals("")) {
365                                         log.error("HS Name Format mapping not set.  Add a (nameMapping) attribute to <HSNameFormat>.");
366                                         throw new ServiceProviderMapperException("Required configuration not specified.");
367                                 }
368
369                                 if (nameMapper.getNameIdentifierMappingById(hsNameFormatId) == null) {
370                                         log.error("Relying Party HS Name Format refers to a name mapping that is not loaded.");
371                                         throw new ServiceProviderMapperException("Required configuration not specified.");
372                                 }
373                         }
374
375                         // Load the credential for signing
376                         String credentialName = ((Element) partyConfig).getAttribute("signingCredential");
377                         Credential signingCredential = credentials.getCredential(credentialName);
378                         if (signingCredential == null) {
379                                 if (credentialName == null || credentialName.equals("")) {
380                                         log.error("Relying Party credential not set.  Add a (signingCredential) "
381                                                         + "attribute to <RelyingParty>.");
382                                         throw new ServiceProviderMapperException("Required configuration not specified.");
383                                 } else {
384                                         log.error("Relying Party credential invalid.  Fix the (signingCredential) attribute "
385                                                         + "on <RelyingParty>.");
386                                         throw new ServiceProviderMapperException("Required configuration is invalid.");
387                                 }
388
389                         }
390
391                         // Initialize and Identity Provider object for this use by this relying party
392                         identityProvider = new RelyingPartyIdentityProvider(overridenOriginProviderId != null
393                                         ? overridenOriginProviderId
394                                         : configuration.getProviderId(), signingCredential);
395
396                 }
397
398                 public String getProviderId() {
399
400                         return name;
401                 }
402
403                 public String getName() {
404
405                         return name;
406                 }
407
408                 public IdentityProvider getIdentityProvider() {
409
410                         return identityProvider;
411                 }
412
413                 public boolean isLegacyProvider() {
414
415                         return false;
416                 }
417
418                 public String getHSNameFormatId() {
419
420                         return hsNameFormatId;
421                 }
422
423                 public URI getDefaultAuthMethod() {
424
425                         if (overridenDefaultAuthMethod != null) {
426                                 return overridenDefaultAuthMethod;
427                         } else {
428                                 return configuration.getDefaultAuthMethod();
429                         }
430                 }
431
432                 public URL getAAUrl() {
433
434                         if (overridenAAUrl != null) {
435                                 return overridenAAUrl;
436                         } else {
437                                 return configuration.getAAUrl();
438                         }
439                 }
440
441                 public boolean passThruErrors() {
442
443                         if (passThruIsOverriden) {
444                                 return overridenPassThruErrors;
445                         } else {
446                                 return configuration.passThruErrors();
447                         }
448                 }
449
450                 public boolean forceAttributePush() {
451
452                         return forceAttributePush;
453                 }
454
455                 public boolean forceAttributeNoPush() {
456
457                         return forceAttributeNoPush;
458                 }
459
460                 public boolean defaultToPOSTProfile() {
461
462                         return defaultToPOST;
463                 }
464
465                 public boolean wantsAssertionsSigned() {
466
467                         return wantsAssertionsSigned;
468                 }
469
470                 public int getPreferredArtifactType() {
471
472                         return preferredArtifactType;
473                 }
474
475                 public String getDefaultTarget() {
476
477                         return defaultTarget;
478                 }
479
480                 public boolean wantsSchemaHack() {
481
482                         return wantsSchemaHack;
483                 }
484
485                 /**
486                  * Default identity provider implementation.
487                  * 
488                  * @author Walter Hoehn
489                  */
490                 protected class RelyingPartyIdentityProvider implements IdentityProvider {
491
492                         private String providerId;
493                         private Credential credential;
494
495                         public RelyingPartyIdentityProvider(String providerId, Credential credential) {
496
497                                 this.providerId = providerId;
498                                 this.credential = credential;
499                         }
500
501                         /*
502                          * @see edu.internet2.middleware.shibboleth.common.IdentityProvider#getProviderId()
503                          */
504                         public String getProviderId() {
505
506                                 return providerId;
507                         }
508
509                         /*
510                          * @see edu.internet2.middleware.shibboleth.common.IdentityProvider#getSigningCredential()
511                          */
512                         public Credential getSigningCredential() {
513
514                                 return credential;
515                         }
516                 }
517
518         }
519
520         /**
521          * Relying party implementation wrapper for relying parties that are groups.
522          * 
523          * @author Walter Hoehn
524          */
525         class RelyingPartyGroupWrapper implements RelyingParty {
526
527                 private RelyingParty wrapped;
528                 private String providerId;
529
530                 RelyingPartyGroupWrapper(RelyingParty wrapped, String providerId) {
531
532                         this.wrapped = wrapped;
533                         this.providerId = providerId;
534                 }
535
536                 public String getName() {
537
538                         return wrapped.getName();
539                 }
540
541                 public boolean isLegacyProvider() {
542
543                         return false;
544                 }
545
546                 public IdentityProvider getIdentityProvider() {
547
548                         return wrapped.getIdentityProvider();
549                 }
550
551                 public String getProviderId() {
552
553                         return providerId;
554                 }
555
556                 public String getHSNameFormatId() {
557
558                         return wrapped.getHSNameFormatId();
559                 }
560
561                 public URL getAAUrl() {
562
563                         return wrapped.getAAUrl();
564                 }
565
566                 public URI getDefaultAuthMethod() {
567
568                         return wrapped.getDefaultAuthMethod();
569                 }
570
571                 public boolean passThruErrors() {
572
573                         return wrapped.passThruErrors();
574                 }
575
576                 public boolean forceAttributePush() {
577
578                         return wrapped.forceAttributePush();
579                 }
580
581                 public boolean forceAttributeNoPush() {
582
583                         return wrapped.forceAttributeNoPush();
584                 }
585
586                 public boolean defaultToPOSTProfile() {
587
588                         return wrapped.defaultToPOSTProfile();
589                 }
590
591                 public boolean wantsAssertionsSigned() {
592
593                         return wrapped.wantsAssertionsSigned();
594                 }
595
596                 public int getPreferredArtifactType() {
597
598                         return wrapped.getPreferredArtifactType();
599                 }
600
601                 public String getDefaultTarget() {
602
603                         return wrapped.getDefaultTarget();
604                 }
605
606                 public boolean wantsSchemaHack() {
607
608                         return wrapped.wantsSchemaHack();
609                 }
610         }
611
612         /**
613          * Relying party implementation wrapper for anonymous service providers.
614          * 
615          * @author Walter Hoehn
616          */
617         protected class UnknownProviderWrapper implements RelyingParty {
618
619                 protected RelyingParty wrapped;
620                 protected String providerId;
621
622                 protected UnknownProviderWrapper(RelyingParty wrapped, String providerId) {
623
624                         this.wrapped = wrapped;
625                         this.providerId = providerId;
626                 }
627
628                 public String getName() {
629
630                         return wrapped.getName();
631                 }
632
633                 public IdentityProvider getIdentityProvider() {
634
635                         return wrapped.getIdentityProvider();
636                 }
637
638                 public String getProviderId() {
639
640                         return providerId;
641                 }
642
643                 public String getHSNameFormatId() {
644
645                         return wrapped.getHSNameFormatId();
646                 }
647
648                 public boolean isLegacyProvider() {
649
650                         return wrapped.isLegacyProvider();
651                 }
652
653                 public URL getAAUrl() {
654
655                         return wrapped.getAAUrl();
656                 }
657
658                 public URI getDefaultAuthMethod() {
659
660                         return wrapped.getDefaultAuthMethod();
661                 }
662
663                 public boolean passThruErrors() {
664
665                         return wrapped.passThruErrors();
666                 }
667
668                 public boolean forceAttributePush() {
669
670                         return false;
671                 }
672
673                 public boolean forceAttributeNoPush() {
674
675                         return false;
676                 }
677
678                 public boolean defaultToPOSTProfile() {
679
680                         return true;
681                 }
682
683                 public boolean wantsAssertionsSigned() {
684
685                         return wrapped.wantsAssertionsSigned();
686                 }
687
688                 public int getPreferredArtifactType() {
689
690                         return wrapped.getPreferredArtifactType();
691                 }
692
693                 public String getDefaultTarget() {
694
695                         return wrapped.getDefaultTarget();
696                 }
697
698                 public boolean wantsSchemaHack() {
699
700                         return wrapped.wantsSchemaHack();
701                 }
702         }
703
704         /**
705          * Relying party wrapper for Shibboleth &lt;=1.1 service providers.
706          * 
707          * @author Walter Hoehn
708          */
709         class LegacyWrapper extends UnknownProviderWrapper implements RelyingParty {
710
711                 LegacyWrapper(RelyingParty wrapped) {
712
713                         super(wrapped, null);
714                 }
715
716                 public boolean isLegacyProvider() {
717
718                         return true;
719                 }
720
721                 public String getHSNameFormatId() {
722
723                         return ((RelyingParty) wrapped).getHSNameFormatId();
724                 }
725
726                 public URL getAAUrl() {
727
728                         return ((RelyingParty) wrapped).getAAUrl();
729                 }
730
731                 public URI getDefaultAuthMethod() {
732
733                         return ((RelyingParty) wrapped).getDefaultAuthMethod();
734                 }
735         }
736
737         /**
738          * Relying party wrapper for providers for which we have no metadata
739          * 
740          * @author Walter Hoehn
741          */
742         class NoMetadataWrapper extends UnknownProviderWrapper implements RelyingParty {
743
744                 NoMetadataWrapper(RelyingParty wrapped) {
745
746                         super(wrapped, null);
747                 }
748
749                 public String getHSNameFormatId() {
750
751                         return ((RelyingParty) wrapped).getHSNameFormatId();
752                 }
753
754                 public URL getAAUrl() {
755
756                         return ((RelyingParty) wrapped).getAAUrl();
757                 }
758
759                 public URI getDefaultAuthMethod() {
760
761                         return ((RelyingParty) wrapped).getDefaultAuthMethod();
762                 }
763         }
764 }