1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.springframework.extensions.webscripts.servlet.mvc;
20
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.StringTokenizer;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.springframework.extensions.config.ConfigService;
31 import org.springframework.extensions.config.RemoteConfigElement;
32 import org.springframework.extensions.config.RemoteConfigElement.EndpointDescriptor;
33 import org.springframework.extensions.config.RemoteConfigElement.IdentityType;
34 import org.springframework.extensions.surf.exception.WebScriptsPlatformException;
35 import org.springframework.extensions.surf.util.Base64;
36 import org.springframework.extensions.webscripts.connector.Connector;
37 import org.springframework.extensions.webscripts.connector.ConnectorContext;
38 import org.springframework.extensions.webscripts.connector.ConnectorService;
39 import org.springframework.extensions.webscripts.connector.Credentials;
40 import org.springframework.extensions.webscripts.connector.CredentialsImpl;
41 import org.springframework.extensions.webscripts.connector.HttpMethod;
42 import org.springframework.extensions.webscripts.connector.Response;
43 import org.springframework.web.servlet.HandlerMapping;
44 import org.springframework.web.servlet.ModelAndView;
45 import org.springframework.web.servlet.mvc.AbstractController;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public class EndPointProxyController extends AbstractController
75 {
76 private static final String USER_ID = "USER_ID";
77 private static final String PARAM_ALF_TICKET = "alf_ticket";
78
79 private static Log logger = LogFactory.getLog(EndPointProxyController.class);
80
81 private static final long serialVersionUID = -176412355613122789L;
82
83 protected ConfigService configService;
84 protected RemoteConfigElement config;
85 protected ConnectorService connectorService;
86
87
88
89
90
91
92 public void setConfigService(ConfigService configService)
93 {
94 this.configService = configService;
95 }
96
97
98
99
100
101
102 public void setConnectorService(ConnectorService connectorService)
103 {
104 this.connectorService = connectorService;
105 }
106
107
108
109
110
111
112 public RemoteConfigElement getRemoteConfig()
113 {
114 if (this.config == null)
115 {
116
117 this.config = (RemoteConfigElement) configService.getConfig("Remote").getConfigElement("remote");
118 }
119
120 return this.config;
121 }
122
123
124
125
126 public ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse res) throws Exception
127 {
128 ModelAndView mav = null;
129
130
131 String uri = (String) req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
132
133
134 StringTokenizer t = new StringTokenizer(uri, "/");
135 if (!t.hasMoreTokens())
136 {
137 throw new IllegalArgumentException("Proxy URL did not specify endpoint id.");
138 }
139 String endpointId = t.nextToken();
140
141
142 StringBuilder buf = new StringBuilder(64);
143 if (t.hasMoreTokens())
144 {
145 do
146 {
147 buf.append('/');
148 buf.append(t.nextToken());
149 } while (t.hasMoreTokens());
150 }
151 else
152 {
153
154
155 buf.append('/');
156 }
157
158 try
159 {
160
161 EndpointDescriptor descriptor = getRemoteConfig().getEndpointDescriptor(endpointId);
162 if (descriptor == null || descriptor.getUnsecure())
163 {
164
165 throw new WebScriptsPlatformException("Invalid EndPoint Id: " + endpointId);
166 }
167
168
169
170
171 String ticket = req.getParameter(PARAM_ALF_TICKET);
172
173
174 Connector connector;
175 String userId = (String)req.getSession().getAttribute(USER_ID);
176 if (userId != null)
177 {
178
179 connector = this.connectorService.getConnector(endpointId, userId, req.getSession());
180 }
181 else if (ticket != null ||
182 descriptor.getIdentity() == IdentityType.NONE ||
183 descriptor.getIdentity() == IdentityType.DECLARED ||
184 descriptor.getExternalAuth())
185 {
186
187
188
189 connector = this.connectorService.getConnector(endpointId, req.getSession());
190 }
191 else if (descriptor.getBasicAuth())
192 {
193
194 String authorization = req.getHeader("Authorization");
195 if (authorization == null || authorization.length() == 0)
196 {
197 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED,
198 "No USER_ID found in session and requested endpoint requires authentication.");
199 res.setHeader("WWW-Authenticate", "Basic realm=\"Alfresco\"");
200
201
202
203 return null;
204 }
205 else
206 {
207
208 String[] authParts = authorization.split(" ");
209 if (!authParts[0].equalsIgnoreCase("basic"))
210 {
211 throw new WebScriptsPlatformException("Authorization '" + authParts[0] + "' not supported.");
212 }
213
214 String[] values = new String(Base64.decode(authParts[1])).split(":");
215 if (values.length == 2)
216 {
217 if (logger.isDebugEnabled())
218 logger.debug("Authenticating (BASIC HTTP) user " + values[0]);
219
220
221
222
223 connector = this.connectorService.getConnector(endpointId, values[0], req.getSession());
224 Credentials credentials = new CredentialsImpl(endpointId);
225 credentials.setProperty(Credentials.CREDENTIAL_USERNAME, values[0]);
226 credentials.setProperty(Credentials.CREDENTIAL_PASSWORD, values[1]);
227 connector.setCredentials(credentials);
228 }
229 else
230 {
231 throw new WebScriptsPlatformException("Authorization request did not provide user/pass.");
232 }
233 }
234 }
235 else
236 {
237 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED,
238 "No USER_ID found in session and requested endpoint requires authentication.");
239 return null;
240 }
241
242
243 ConnectorContext context;
244 if (ticket == null)
245 {
246 context = new ConnectorContext();
247 }
248 else
249 {
250
251 Map<String, String> params = new HashMap<String, String>(1, 1.0f);
252 params.put(PARAM_ALF_TICKET, ticket);
253 context = new ConnectorContext(params, null);
254 }
255 context.setContentType(req.getContentType());
256 context.setMethod(HttpMethod.valueOf(req.getMethod().toUpperCase()));
257
258
259 String q = req.getQueryString();
260 String url = buf.toString() + (q != null && q.length() != 0 ? "?" + q : "");
261
262 if (logger.isDebugEnabled())
263 {
264 logger.debug("EndPointProxyServlet preparing to proxy:");
265 logger.debug(" - endpointId: " + endpointId);
266 logger.debug(" - userId: " + userId);
267 logger.debug(" - connector: " + connector);
268 logger.debug(" - method: " + context.getMethod());
269 logger.debug(" - url: " + url);
270 }
271
272
273 Response response = connector.call(url, context, req, res);
274
275 if (logger.isDebugEnabled())
276 {
277 logger.debug("Return code: " + response.getStatus().getCode());
278 if (response.getStatus().getCode() == 500)
279 {
280 logger.debug("Error detected: " + response.getStatus().getMessage() + "\n" +
281 response.getStatus().getException().toString());
282 }
283 }
284 }
285 catch (Throwable err)
286 {
287
288 throw new WebScriptsPlatformException("Error during endpoint proxy processing: " + err.getMessage(), err);
289 }
290
291 return mav;
292 }
293 }
294
295