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