1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.bindings.spi;
20
21 import java.io.UnsupportedEncodingException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.concurrent.locks.ReentrantReadWriteLock;
28
29 import org.apache.chemistry.opencmis.client.bindings.spi.cookies.CmisCookieManager;
30 import org.apache.chemistry.opencmis.commons.SessionParameter;
31 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
32 import org.apache.chemistry.opencmis.commons.impl.Base64;
33 import org.apache.chemistry.opencmis.commons.impl.DateTimeHelper;
34 import org.apache.chemistry.opencmis.commons.impl.IOUtils;
35 import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.Element;
38
39
40
41
42
43
44
45 public class StandardAuthenticationProvider extends AbstractAuthenticationProvider {
46
47 private static final long serialVersionUID = 1L;
48
49 protected static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
50 protected static final String WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
51
52 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
53
54 private CmisCookieManager cookieManager;
55 private Map<String, List<String>> fixedHeaders = new HashMap<String, List<String>>();
56 private String csrfHeader;
57 private String csrfValue = "fetch";
58
59 @Override
60 public void setSession(BindingSession session) {
61 super.setSession(session);
62
63 if (getHandleCookies() && cookieManager == null) {
64 cookieManager = new CmisCookieManager(session.getSessionId());
65 }
66
67 boolean sendBasicAuth = getSendBasicAuth();
68
69
70 if (sendBasicAuth) {
71
72 String user = getUser();
73 String password = getPassword();
74
75
76 if (user != null) {
77 fixedHeaders.put("Authorization", createBasicAuthHeaderValue(user, password));
78 }
79 }
80
81 boolean sendBearerToken = getSendBearerToken();
82
83
84 if (sendBearerToken) {
85 String token = getBearerToken();
86
87
88 if (token != null) {
89 fixedHeaders.put("Authorization", Collections.singletonList("Bearer " + token));
90 }
91 }
92
93
94 if (getProxyUser() != null) {
95
96 String proxyUser = getProxyUser();
97 String proxyPassword = getProxyPassword();
98
99 fixedHeaders.put("Proxy-Authorization", createBasicAuthHeaderValue(proxyUser, proxyPassword));
100 }
101
102
103 csrfHeader = getCsrfHeader();
104
105
106 addSessionParameterHeadersToFixedHeaders();
107 }
108
109 @Override
110 public Map<String, List<String>> getHTTPHeaders(String url) {
111 Map<String, List<String>> result = new HashMap<String, List<String>>(fixedHeaders);
112
113 lock.readLock().lock();
114 try {
115
116 if (cookieManager != null) {
117 Map<String, List<String>> cookies = cookieManager.get(url, result);
118 if (!cookies.isEmpty()) {
119 result.putAll(cookies);
120 }
121 }
122
123
124 if (csrfHeader != null && csrfValue != null) {
125 result.put(csrfHeader, Collections.singletonList(csrfValue));
126 }
127 } finally {
128 lock.readLock().unlock();
129 }
130
131 return result.isEmpty() ? null : result;
132 }
133
134 @Override
135 public void putResponseHeaders(String url, int statusCode, Map<String, List<String>> headers) {
136 lock.writeLock().lock();
137 try {
138
139 if (cookieManager != null) {
140 if (headers != null && headers.size() > 0) {
141 cookieManager.put(url, headers);
142 }
143 }
144
145
146 if (csrfHeader != null) {
147 for (Map.Entry<String, List<String>> header : headers.entrySet()) {
148 if (csrfHeader.equalsIgnoreCase(header.getKey())) {
149 List<String> values = header.getValue();
150 if (values != null && values.size() > 0) {
151 csrfValue = values.get(0);
152 }
153 break;
154 }
155 }
156 }
157 } finally {
158 lock.writeLock().unlock();
159 }
160 }
161
162 @Override
163 public Element getSOAPHeaders(Object portObject) {
164
165 if (!getSendUsernameToken()) {
166 return null;
167 }
168
169
170 String user = getUser();
171 String password = getPassword();
172
173
174 if (user == null) {
175 return null;
176 }
177
178 if (password == null) {
179 password = "";
180 }
181
182
183 long created = System.currentTimeMillis();
184 long expires = created + 24 * 60 * 60 * 1000;
185
186
187 try {
188 Document document = XMLUtils.newDomDocument();
189
190 Element wsseSecurityElement = document.createElementNS(WSSE_NAMESPACE, "Security");
191
192 Element wsuTimestampElement = document.createElementNS(WSU_NAMESPACE, "Timestamp");
193 wsseSecurityElement.appendChild(wsuTimestampElement);
194
195 Element tsCreatedElement = document.createElementNS(WSU_NAMESPACE, "Created");
196 tsCreatedElement.appendChild(document.createTextNode(DateTimeHelper.formatXmlDateTime(created)));
197 wsuTimestampElement.appendChild(tsCreatedElement);
198
199 Element tsExpiresElement = document.createElementNS(WSU_NAMESPACE, "Expires");
200 tsExpiresElement.appendChild(document.createTextNode(DateTimeHelper.formatXmlDateTime(expires)));
201 wsuTimestampElement.appendChild(tsExpiresElement);
202
203 Element usernameTokenElement = document.createElementNS(WSSE_NAMESPACE, "UsernameToken");
204 wsseSecurityElement.appendChild(usernameTokenElement);
205
206 Element usernameElement = document.createElementNS(WSSE_NAMESPACE, "Username");
207 usernameElement.appendChild(document.createTextNode(user));
208 usernameTokenElement.appendChild(usernameElement);
209
210 Element passwordElement = document.createElementNS(WSSE_NAMESPACE, "Password");
211 passwordElement.appendChild(document.createTextNode(password));
212 passwordElement.setAttribute("Type",
213 "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
214 usernameTokenElement.appendChild(passwordElement);
215
216 Element createdElement = document.createElementNS(WSU_NAMESPACE, "Created");
217 createdElement.appendChild(document.createTextNode(DateTimeHelper.formatXmlDateTime(created)));
218 usernameTokenElement.appendChild(createdElement);
219
220 return wsseSecurityElement;
221 } catch (Exception e) {
222
223 throw new CmisRuntimeException("Could not build SOAP header: " + e.getMessage(), e);
224 }
225 }
226
227
228
229
230
231 protected Map<String, List<String>> getFixedHeaders() {
232 return fixedHeaders;
233 }
234
235
236
237
238
239
240 protected void addSessionParameterHeadersToFixedHeaders() {
241 int x = 0;
242 Object headerParam;
243 while ((headerParam = getSession().get(SessionParameter.HEADER + "." + x)) != null) {
244 String header = headerParam.toString();
245 int colon = header.indexOf(':');
246 if (colon > -1) {
247 String key = header.substring(0, colon).trim();
248 if (key.length() > 0) {
249 String value = header.substring(colon + 1).trim();
250 List<String> values = fixedHeaders.get(key);
251 if (values == null) {
252 fixedHeaders.put(key, Collections.singletonList(value));
253 } else {
254 List<String> newValues = new ArrayList<String>(values);
255 newValues.add(value);
256 fixedHeaders.put(key, newValues);
257 }
258 }
259 }
260 x++;
261 }
262 }
263
264
265
266
267
268 protected List<String> createBasicAuthHeaderValue(String username, String password) {
269 if (password == null) {
270 password = "";
271 }
272
273 Object charset = getSession().get(SessionParameter.AUTH_HTTP_BASIC_CHARSET);
274 if (charset instanceof String) {
275 charset = ((String) charset).trim();
276 } else {
277 charset = IOUtils.UTF8;
278 }
279
280 byte[] usernamePassword;
281 try {
282 usernamePassword = (username + ":" + password).getBytes((String) charset);
283 } catch (UnsupportedEncodingException e) {
284 throw new CmisRuntimeException("Unsupported encoding '" + charset + "'!", e);
285 }
286
287 return Collections.singletonList("Basic " + Base64.encodeBytes(usernamePassword));
288 }
289
290
291
292
293
294 protected boolean getSendBasicAuth() {
295 return getSession().get(SessionParameter.AUTH_HTTP_BASIC, false);
296 }
297
298
299
300
301 protected boolean getSendBearerToken() {
302 return getSession().get(SessionParameter.AUTH_OAUTH_BEARER, false);
303 }
304
305
306
307
308 protected boolean getSendUsernameToken() {
309 return getSession().get(SessionParameter.AUTH_SOAP_USERNAMETOKEN, false);
310 }
311
312
313
314
315 protected boolean getHandleCookies() {
316 Object value = getSession().get(SessionParameter.COOKIES);
317
318 if (value instanceof Boolean) {
319 return ((Boolean) value).booleanValue();
320 } else if (value instanceof String) {
321 return Boolean.parseBoolean((String) value);
322 } else if (value == null) {
323 return getCsrfHeader() != null;
324 }
325
326 return false;
327 }
328 }