1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.common.relyingparty.provider;
18
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.concurrent.locks.Lock;
23
24 import org.opensaml.saml2.metadata.EntitiesDescriptor;
25 import org.opensaml.saml2.metadata.EntityDescriptor;
26 import org.opensaml.saml2.metadata.provider.MetadataProvider;
27 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.context.ApplicationContext;
31
32 import edu.internet2.middleware.shibboleth.common.config.BaseReloadableService;
33 import edu.internet2.middleware.shibboleth.common.config.relyingparty.RelyingPartyGroup;
34 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
35 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfigurationManager;
36 import edu.internet2.middleware.shibboleth.common.service.ServiceException;
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class SAMLMDRelyingPartyConfigurationManager extends BaseReloadableService implements
51 RelyingPartyConfigurationManager {
52
53
54 public static final String ANONYMOUS_RP_NAME = "anonymous";
55
56
57 public static final String DEFAULT_RP_NAME = "default";
58
59
60 private final Logger log = LoggerFactory.getLogger(SAMLMDRelyingPartyConfigurationManager.class);
61
62
63 private MetadataProvider metadataProvider;
64
65
66 private HashMap<String, RelyingPartyConfiguration> rpConfigs;
67
68
69 public SAMLMDRelyingPartyConfigurationManager() {
70 super();
71 rpConfigs = new HashMap<String, RelyingPartyConfiguration>();
72 }
73
74
75 public RelyingPartyConfiguration getAnonymousRelyingConfiguration() {
76 Lock readLock = getReadWriteLock().readLock();
77 readLock.lock();
78 try {
79 return rpConfigs.get(ANONYMOUS_RP_NAME);
80 } finally {
81 readLock.unlock();
82 }
83 }
84
85
86 public RelyingPartyConfiguration getDefaultRelyingPartyConfiguration() {
87 Lock readLock = getReadWriteLock().readLock();
88 readLock.lock();
89 try {
90 return rpConfigs.get(DEFAULT_RP_NAME);
91 } finally {
92 readLock.unlock();
93 }
94 }
95
96
97
98
99
100
101 public MetadataProvider getMetadataProvider() {
102 Lock readLock = getReadWriteLock().readLock();
103 readLock.lock();
104 try {
105 return metadataProvider;
106 } finally {
107 readLock.unlock();
108 }
109 }
110
111
112
113
114
115
116 public void setMetadataProvider(MetadataProvider provider) {
117 metadataProvider = provider;
118 }
119
120
121 public RelyingPartyConfiguration getRelyingPartyConfiguration(String relyingPartyEntityID) {
122 Lock readLock = getReadWriteLock().readLock();
123 readLock.lock();
124
125 try {
126 log.debug("Looking up relying party configuration for {}", relyingPartyEntityID);
127 if (rpConfigs.containsKey(relyingPartyEntityID)) {
128 log.debug("Custom relying party configuration found for {}", relyingPartyEntityID);
129 return rpConfigs.get(relyingPartyEntityID);
130 }
131
132 log.debug("No custom relying party configuration found for {}, looking up configuration based on metadata groups.",
133 relyingPartyEntityID);
134 try {
135 if (metadataProvider == null) {
136 log.debug("No metadata provider available, unable to lookup configuration based on entity group");
137 } else {
138 EntityDescriptor entityDescriptor = metadataProvider.getEntityDescriptor(relyingPartyEntityID);
139 if (entityDescriptor != null) {
140 EntitiesDescriptor entityGroup = (EntitiesDescriptor) entityDescriptor.getParent();
141 while (entityGroup != null) {
142 if (rpConfigs.containsKey(entityGroup.getName())) {
143 log.debug("Relying party configuration found for {} as member of metadata group {}",
144 relyingPartyEntityID, entityGroup.getName());
145 return rpConfigs.get(entityGroup.getName());
146 }
147 entityGroup = (EntitiesDescriptor) entityGroup.getParent();
148 }
149 }
150 }
151 } catch (MetadataProviderException e) {
152 log.error("Error fetching metadata for relying party " + relyingPartyEntityID, e);
153 }
154
155 log.debug("No custom or group-based relying party configuration found for {}. Using default relying party configuration.",
156 relyingPartyEntityID);
157 return getDefaultRelyingPartyConfiguration();
158 } finally {
159 readLock.unlock();
160 }
161 }
162
163
164 public Map<String, RelyingPartyConfiguration> getRelyingPartyConfigurations() {
165 return rpConfigs;
166 }
167
168
169 protected void onNewContextCreated(ApplicationContext newServiceContext) throws ServiceException {
170 MetadataProvider oldProvider = metadataProvider;
171 HashMap<String, RelyingPartyConfiguration> oldRpConfigs = rpConfigs;
172 try {
173 String[] relyingPartyGroupNames = newServiceContext.getBeanNamesForType(RelyingPartyGroup.class);
174 RelyingPartyGroup newRpGroup = (RelyingPartyGroup) newServiceContext.getBean(relyingPartyGroupNames[0]);
175
176 metadataProvider = newRpGroup.getMetadataProvider();
177
178 HashMap<String, RelyingPartyConfiguration> newRpConfigs = new HashMap<String, RelyingPartyConfiguration>();
179 List<RelyingPartyConfiguration> loadRpConfigs = newRpGroup.getRelyingParties();
180 if (loadRpConfigs != null) {
181 for (RelyingPartyConfiguration newRpConfig : loadRpConfigs) {
182 newRpConfigs.put(newRpConfig.getRelyingPartyId(), newRpConfig);
183 log.debug("Registering configuration for relying party: {}", newRpConfig.getRelyingPartyId());
184 }
185 }
186 newRpConfigs.put(ANONYMOUS_RP_NAME, newRpGroup.getAnonymousRP());
187 newRpConfigs.put(DEFAULT_RP_NAME, newRpGroup.getDefaultRP());
188 rpConfigs = newRpConfigs;
189
190 } catch (Exception e) {
191 metadataProvider = oldProvider;
192 rpConfigs = oldRpConfigs;
193 throw new ServiceException(getId() + " configuration is not valid, retaining old configuration", e);
194 }
195 }
196 }