1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package edu.internet2.middleware.shibboleth.common.config.metadata;
19
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.security.cert.X509Certificate;
23
24 import javax.net.ssl.X509TrustManager;
25 import javax.xml.namespace.QName;
26
27 import org.apache.commons.httpclient.HttpClient;
28 import org.apache.commons.httpclient.UsernamePasswordCredentials;
29 import org.apache.commons.httpclient.auth.AuthScope;
30 import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
31 import org.opensaml.ws.soap.client.http.HttpClientBuilder;
32 import org.opensaml.ws.soap.client.http.TLSProtocolSocketFactory;
33 import org.opensaml.xml.util.DatatypeHelper;
34 import org.opensaml.xml.util.XMLHelper;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.springframework.beans.factory.BeanCreationException;
38 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
39 import org.springframework.beans.factory.xml.ParserContext;
40 import org.w3c.dom.Element;
41
42 import edu.internet2.middleware.shibboleth.common.config.SpringConfigurationUtils;
43
44
45
46
47 public class HTTPMetadataProviderBeanDefinitionParser extends AbstractReloadingMetadataProviderBeanDefinitionParser {
48
49
50 public static final QName TYPE_NAME = new QName(MetadataNamespaceHandler.NAMESPACE, "HTTPMetadataProvider");
51
52
53 private Logger log = LoggerFactory.getLogger(HTTPMetadataProviderBeanDefinitionParser.class);
54
55
56 protected Class getBeanClass(Element element) {
57 return HTTPMetadataProvider.class;
58 }
59
60
61 protected void doParse(Element config, ParserContext parserContext, BeanDefinitionBuilder builder) {
62 String providerId = getProviderId(config);
63
64 super.doParse(config, parserContext, builder);
65
66 String metadataURL = DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "metadataURL"));
67 URL metadataURI = null;
68 try {
69 metadataURI = new URL(metadataURL);
70 } catch (MalformedURLException e) {
71 throw new BeanCreationException("metadataURL attribute for metadata provider " + providerId
72 + " must be present and must contain a valid URL");
73 }
74
75 HttpClient httpClient = buildHttpClient(config, providerId, metadataURI);
76 builder.addConstructorArgValue(httpClient);
77
78 log.debug("Metadata provider '{}' metadata URL: {}", providerId, metadataURL);
79 builder.addConstructorArgValue(metadataURL);
80 }
81
82
83
84
85
86
87
88
89
90
91 protected HttpClient buildHttpClient(Element config, String providerId, URL metadataURL) {
92 HttpClientBuilder builder = new HttpClientBuilder();
93
94 int requestTimeout = 5000;
95 if (config.hasAttributeNS(null, "requestTimeout")) {
96 requestTimeout = (int) SpringConfigurationUtils.parseDurationToMillis(
97 "'requestTimeout' on metadata provider " + providerId,
98 config.getAttributeNS(null, "requestTimeout"), 0);
99 }
100 log.debug("Metadata provider '{}' HTTP request timeout: {}ms", providerId, requestTimeout);
101 builder.setConnectionTimeout(requestTimeout);
102
103 if (metadataURL.getProtocol().equalsIgnoreCase("https")) {
104 boolean disregardSslCertificate = false;
105 if (config.hasAttributeNS(null, "disregardSslCertificate")) {
106 disregardSslCertificate = XMLHelper.getAttributeValueAsBoolean(config.getAttributeNodeNS(null,
107 "disregardSslCertificate"));
108 }
109
110 log.debug("Metadata provider '{}' disregards server SSL certificate: {}", providerId,
111 disregardSslCertificate);
112 if (disregardSslCertificate) {
113 builder.setHttpsProtocolSocketFactory(new TLSProtocolSocketFactory(null, buildNoTrustTrustManager()));
114 }
115 }
116
117 setHttpProxySettings(builder, config, providerId);
118
119 HttpClient httpClient = builder.buildClient();
120 setHttpBasicAuthSettings(httpClient, config, providerId, metadataURL);
121
122 return httpClient;
123 }
124
125
126
127
128
129
130 protected X509TrustManager buildNoTrustTrustManager() {
131 X509TrustManager noTrustManager = new X509TrustManager() {
132
133
134 public void checkClientTrusted(X509Certificate[] certs, String auth) {
135 }
136
137
138 public void checkServerTrusted(X509Certificate[] certs, String auth) {
139 }
140
141
142 public X509Certificate[] getAcceptedIssuers() {
143 return new X509Certificate[] {};
144 }
145 };
146
147 return noTrustManager;
148 }
149
150
151
152
153
154
155
156
157 protected void setHttpProxySettings(HttpClientBuilder builder, Element config, String providerId) {
158 String proxyHost = DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "proxyHost"));
159 if (proxyHost == null) {
160 return;
161 }
162 log.debug("Metadata provider '{}' HTTP proxy host: {}", providerId, proxyHost);
163 builder.setProxyHost(proxyHost);
164
165 if (config.hasAttributeNS(null, "proxyPort")) {
166 int proxyPort = Integer.parseInt(config.getAttributeNS(null, "proxyPort"));
167 log.debug("Metadata provider '{}' HTTP proxy port: ", providerId, proxyPort);
168 builder.setProxyPort(proxyPort);
169 }
170
171 String proxyUser = DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "proxyUser"));
172 if (proxyUser != null) {
173 log.debug("Metadata provider '{}' HTTP proxy username: ", providerId, proxyUser);
174 builder.setProxyUsername(proxyUser);
175 log.debug("Metadata provider '{}' HTTP proxy password not shown", providerId);
176 builder.setProxyPassword(DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "proxyPassword")));
177 }
178 }
179
180
181
182
183
184
185
186
187
188 protected void setHttpBasicAuthSettings(HttpClient httpClient, Element config, String providerId, URL metadataURL) {
189 String authUser = DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "basicAuthUser"));
190 if (authUser == null) {
191 return;
192 }
193 log.debug("Metadata provider '{}' HTTP Basic Auth username: {}", providerId, authUser);
194
195 String authPassword = DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "basicAuthPassword"));
196 log.debug("Metadata provider '{}' HTTP Basic Auth password not show", providerId);
197
198 UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(authUser, authPassword);
199 AuthScope authScope = new AuthScope(metadataURL.getHost(), metadataURL.getPort());
200 httpClient.getState().setCredentials(authScope, credentials);
201 }
202 }