This project has retired. For details please refer to its Attic page.
StandardAuthenticationProvider xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.client.bindings.spi;
20  
21  import java.io.UnsupportedEncodingException;
22  import java.text.SimpleDateFormat;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.TimeZone;
28  
29  import javax.xml.parsers.DocumentBuilderFactory;
30  import javax.xml.parsers.ParserConfigurationException;
31  
32  import org.apache.chemistry.opencmis.client.bindings.spi.cookies.CmisCookieManager;
33  import org.apache.chemistry.opencmis.commons.SessionParameter;
34  import org.apache.chemistry.opencmis.commons.impl.Base64;
35  import org.w3c.dom.Document;
36  import org.w3c.dom.Element;
37  
38  /**
39   * Standard authentication provider class.
40   * 
41   * Adds a basic authentication HTTP header and a WS-Security UsernameToken SOAP
42   * header.
43   */
44  public class StandardAuthenticationProvider extends AbstractAuthenticationProvider {
45  
46      private static final long serialVersionUID = 1L;
47  
48      private static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
49      private static final String WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
50  
51      private boolean sendBasicAuth;
52      private boolean sendUsernameToken;
53      private CmisCookieManager cookieManager;
54  
55      @Override
56      public void setSession(BindingSession session) {
57          super.setSession(session);
58  
59          sendBasicAuth = isTrue(SessionParameter.AUTH_HTTP_BASIC);
60          sendUsernameToken = isTrue(SessionParameter.AUTH_SOAP_USERNAMETOKEN);
61  
62          if (isTrue(SessionParameter.COOKIES)) {
63              cookieManager = new CmisCookieManager();
64          }
65      }
66  
67      @Override
68      public Map<String, List<String>> getHTTPHeaders(String url) {
69          Map<String, List<String>> result = new HashMap<String, List<String>>();
70  
71          // authentication
72          if (sendBasicAuth) {
73              // get user and password
74              String user = getUser();
75              String password = getPassword();
76  
77              // if no user is set, don't set basic auth header
78              if (user != null) {
79                  result.put("Authorization", createBasicAuthHeaderValue(user, password));
80              }
81  
82              // get proxy user and password
83              String proxyUser = getProxyUser();
84              String proxyPassword = getProxyPassword();
85  
86              // if no proxy user is set, don't set basic auth header
87              if (proxyUser != null) {
88                  result.put("Proxy-Authorization", createBasicAuthHeaderValue(proxyUser, proxyPassword));
89              }
90          }
91  
92          // cookies
93          if (cookieManager != null) {
94              Map<String, List<String>> cookies = cookieManager.get(url, result);
95              if (!cookies.isEmpty()) {
96                  result.putAll(cookies);
97              }
98          }
99  
100         return result.isEmpty() ? null : result;
101     }
102 
103     @Override
104     public void putResponseHeaders(String url, int statusCode, Map<String, List<String>> headers) {
105         if (cookieManager != null) {
106             cookieManager.put(url, headers);
107         }
108     }
109 
110     @Override
111     public Element getSOAPHeaders(Object portObject) {
112         // only send SOAP header if configured
113         if (!sendUsernameToken) {
114             return null;
115         }
116 
117         // get user and password
118         String user = getUser();
119         String password = getPassword();
120 
121         // if no user is set, don't create SOAP header
122         if (user == null) {
123             return null;
124         }
125 
126         if (password == null) {
127             password = "";
128         }
129 
130         // set time
131         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
132         sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
133         long created = System.currentTimeMillis();
134         long expires = created + 24 * 60 * 60 * 1000; // 24 hours
135 
136         // create the SOAP header
137         try {
138             Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
139 
140             Element wsseSecurityElement = document.createElementNS(WSSE_NAMESPACE, "Security");
141 
142             Element wsuTimestampElement = document.createElementNS(WSU_NAMESPACE, "Timestamp");
143             wsseSecurityElement.appendChild(wsuTimestampElement);
144 
145             Element tsCreatedElement = document.createElementNS(WSU_NAMESPACE, "Created");
146             tsCreatedElement.appendChild(document.createTextNode(sdf.format(created)));
147             wsuTimestampElement.appendChild(tsCreatedElement);
148 
149             Element tsExpiresElement = document.createElementNS(WSU_NAMESPACE, "Expires");
150             tsExpiresElement.appendChild(document.createTextNode(sdf.format(expires)));
151             wsuTimestampElement.appendChild(tsExpiresElement);
152 
153             Element usernameTokenElement = document.createElementNS(WSSE_NAMESPACE, "UsernameToken");
154             wsseSecurityElement.appendChild(usernameTokenElement);
155 
156             Element usernameElement = document.createElementNS(WSSE_NAMESPACE, "Username");
157             usernameElement.appendChild(document.createTextNode(user));
158             usernameTokenElement.appendChild(usernameElement);
159 
160             Element passwordElement = document.createElementNS(WSSE_NAMESPACE, "Password");
161             passwordElement.appendChild(document.createTextNode(password));
162             passwordElement.setAttribute("Type",
163                     "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
164             usernameTokenElement.appendChild(passwordElement);
165 
166             Element createdElement = document.createElementNS(WSU_NAMESPACE, "Created");
167             createdElement.appendChild(document.createTextNode(sdf.format(created)));
168             usernameTokenElement.appendChild(createdElement);
169 
170             return wsseSecurityElement;
171         } catch (ParserConfigurationException e) {
172             // shouldn't happen...
173             e.printStackTrace();
174         }
175 
176         return null;
177     }
178 
179     /**
180      * Creates a basic authentication header value from a username and a
181      * password.
182      */
183     protected List<String> createBasicAuthHeaderValue(String username, String password) {
184         if (password == null) {
185             password = "";
186         }
187 
188         try {
189             return Collections.singletonList("Basic "
190                     + Base64.encodeBytes((username + ":" + password).getBytes("ISO-8859-1")));
191         } catch (UnsupportedEncodingException e) {
192             // shouldn't happen...
193             return Collections.emptyList();
194         }
195     }
196 
197     /**
198      * Returns <code>true</code> if the given parameter exists in the session
199      * and is set to true, <code>false</code> otherwise.
200      */
201     protected boolean isTrue(String parameterName) {
202         Object value = getSession().get(parameterName);
203 
204         if (value instanceof Boolean) {
205             return ((Boolean) value).booleanValue();
206         }
207 
208         if (value instanceof String) {
209             return Boolean.parseBoolean((String) value);
210         }
211 
212         return false;
213     }
214 }