|
17 | 17 |
|
18 | 18 | import java.io.IOException;
|
19 | 19 | import java.io.PrintWriter;
|
| 20 | +import java.io.File; |
20 | 21 | import java.util.Iterator;
|
21 | 22 | import java.util.List;
|
22 | 23 | import java.util.Vector;
|
|
30 | 31 |
|
31 | 32 | import org.apache.commons.configuration.Configuration;
|
32 | 33 | import org.apache.log4j.Logger;
|
| 34 | +import org.apache.log4j.Level; |
33 | 35 | import org.openid4java.OpenIDException;
|
34 | 36 | import org.openid4java.consumer.ConsumerManager;
|
35 | 37 | import org.openid4java.consumer.VerificationResult;
|
|
43 | 45 | import edu.jhu.pha.vospace.SettingsServlet;
|
44 | 46 | import edu.jhu.pha.vospace.api.exceptions.PermissionDeniedException;
|
45 | 47 |
|
| 48 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.Asset; |
| 49 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.OA4MPResponse; |
| 50 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.servlet.ClientServlet; |
| 51 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.servlet.sample.SimpleStartRequest; |
| 52 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.servlet.sample.SimpleReadyServlet; |
| 53 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.storage.AssetStore; |
| 54 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.storage.AssetStoreUtil; |
| 55 | +import edu.uiuc.ncsa.security.core.Identifier; |
| 56 | +import edu.uiuc.ncsa.security.servlet.JSPUtil; |
| 57 | +import edu.uiuc.ncsa.security.util.pkcs.KeyUtil; |
| 58 | + |
| 59 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.OA4MPService; |
| 60 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.ClientEnvironment; |
| 61 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.loader.ClientEnvironmentUtil; |
| 62 | +import edu.uiuc.ncsa.myproxy.oa4mp.client.AssetResponse; |
| 63 | + |
46 | 64 | /** A simple implementation of an OpenID relying party, specialized for VOSpace & VAO OpenID.
|
47 | 65 | * For more sample code, see OpenID4Java's sample code or the USVAO SSO example
|
48 | 66 | * (TODO: get URL once it's in usvao svn). */
|
@@ -89,6 +107,9 @@ private void handle(HttpServletRequest request, HttpServletResponse response)
|
89 | 107 | if (isOpenIdResponse(request)) {
|
90 | 108 | logger.debug("Handle OpenID");
|
91 | 109 | handleOpenidResponse(request, response);
|
| 110 | + } else if (isOA4MPResponse(request)) { |
| 111 | + logger.debug("Handle OA4MP response"); |
| 112 | + handleOA4MPResponse(request, response); |
92 | 113 | } else { // initial login
|
93 | 114 | logger.debug("Initiate");
|
94 | 115 | String userName = checkCertificate(request);
|
@@ -116,7 +137,8 @@ private void handle(HttpServletRequest request, HttpServletResponse response)
|
116 | 137 | logger.debug("Created third party app cookie.");
|
117 | 138 | }
|
118 | 139 |
|
119 |
| - String error = initiateOpenid(request, response, idLess); |
| 140 | + // String error = initiateOpenid(request, response, idLess); |
| 141 | + String error = initiateOA4MP(request, response); |
120 | 142 | if (error != null)
|
121 | 143 | throw new Oops(error);
|
122 | 144 | }
|
@@ -177,6 +199,26 @@ private void handleOpenidResponse(HttpServletRequest request, HttpServletRespons
|
177 | 199 | }
|
178 | 200 | }
|
179 | 201 |
|
| 202 | + private void handleOA4MPResponse(HttpServletRequest request, HttpServletResponse response) |
| 203 | + throws IOException, Oops { |
| 204 | + try { |
| 205 | + logger.debug("IN OA4MP response "); |
| 206 | + ClientEnvironment ce = ClientEnvironmentUtil.load(new File("/etc/vospace/client-cfg.xml")); |
| 207 | + logger.debug("READ FILE "); |
| 208 | + OA4MPService service = new OA4MPService(ce); |
| 209 | + logger.debug("OA4MP SERVICE"); |
| 210 | + String accessToken = request.getParameter("oauth_token"); // from the callback URL |
| 211 | + String verifier = request.getParameter("oauth_verifier"); // from the callback URL |
| 212 | + logger.debug("OA4MP accessToken " + accessToken + " verifier " + verifier); |
| 213 | + AssetResponse assetResponse = service.getCert(accessToken, verifier); |
| 214 | + logger.debug("OA4MP assetResponse " + assetResponse); |
| 215 | + authorizeRequestToken2(request, response, assetResponse.getUsername()); |
| 216 | + } catch (Exception e) { |
| 217 | + logger.info("Exception verifying OA4MP response.", e); |
| 218 | + throw new Oops("Unable to verify OA4MP response: " + e.getMessage()); |
| 219 | + } |
| 220 | + } |
| 221 | + |
180 | 222 | /** OpenID authentication succeeded. */
|
181 | 223 | private void handleAuthenticated
|
182 | 224 | (VerificationResult verification, HttpServletRequest request, HttpServletResponse response)
|
@@ -231,8 +273,8 @@ private void authorizeRequestToken(HttpServletRequest request, HttpServletRespon
|
231 | 273 | String shareId = null;
|
232 | 274 |
|
233 | 275 | if (null != request.getParameter("oauth_token")) {
|
234 |
| - token = request.getParameter("oauth_token"); |
235 |
| - callbackUrl = request.getParameter("oauth_callback"); |
| 276 | + token = request.getParameter("oauth_token"); |
| 277 | + callbackUrl = request.getParameter("oauth_callback"); |
236 | 278 | } else if(cookies != null) {
|
237 | 279 | OauthCookie parsedCookie = null;
|
238 | 280 |
|
@@ -299,6 +341,86 @@ private void authorizeRequestToken(HttpServletRequest request, HttpServletRespon
|
299 | 341 | throw new Oops(e.getMessage());
|
300 | 342 | }
|
301 | 343 | }
|
| 344 | + private void authorizeRequestToken2(HttpServletRequest request, HttpServletResponse response, String username) |
| 345 | + throws Oops { |
| 346 | + |
| 347 | + String token = null, callbackUrl = null; |
| 348 | + |
| 349 | + Cookie[] cookies = request.getCookies(); |
| 350 | + |
| 351 | + String shareId = null; |
| 352 | + logger.debug("IN authorizeRequestToken2 " + cookies.toString()); |
| 353 | + |
| 354 | + // if (null != request.getParameter("oauth_token")) { |
| 355 | + // token = request.getParameter("oauth_token"); |
| 356 | + // callbackUrl = request.getParameter("oauth_callback"); |
| 357 | + // } else if(cookies != null) { |
| 358 | + if(cookies != null) { |
| 359 | + OauthCookie parsedCookie = null; |
| 360 | + |
| 361 | + for (Cookie cookie : cookies) { |
| 362 | + if (cookie.getName().equals(OauthCookie.COOKIE_NAME)){ |
| 363 | + // Remove the temporary 3rd party app cookie |
| 364 | + Cookie removeCookie = new Cookie(OauthCookie.COOKIE_NAME, ""); |
| 365 | + removeCookie.setMaxAge(0); |
| 366 | + response.addCookie(removeCookie); |
| 367 | + try { |
| 368 | + parsedCookie = OauthCookie.create(cookie); |
| 369 | + shareId = parsedCookie.getShareId(); |
| 370 | + if (isBlank(parsedCookie.getRequestToken())) |
| 371 | + throw new Oops("No request token present in oauth cookie (\"" + cookie.getValue() + "\")."); |
| 372 | + logger.debug("Parsed oauth cookie \"" + cookie.getValue() + "\" as \"" + parsedCookie.toString() + "\"."); |
| 373 | + } catch (IOException e) { |
| 374 | + logger.debug("Error parsing cookie. Just removing it."); |
| 375 | + } |
| 376 | + } |
| 377 | + } |
| 378 | + |
| 379 | + if(null != parsedCookie) { |
| 380 | + token = parsedCookie.getRequestToken(); |
| 381 | + callbackUrl = parsedCookie.getCallbackUrl(); |
| 382 | + } |
| 383 | + } |
| 384 | + |
| 385 | + if(null == token) |
| 386 | + throw new Oops("No request token found in request."); |
| 387 | + |
| 388 | + try { |
| 389 | + Token reqToken = MySQLOAuthProvider2.getRequestToken(token); |
| 390 | + if(null == reqToken) |
| 391 | + throw new PermissionDeniedException("401 Unauthorized"); |
| 392 | + if(null != reqToken.getAttributes().getFirst("root_container")){ // pre-shared container accessor |
| 393 | + if(shareId != null) {//already created the share - user bound sharing |
| 394 | + List<String> groupUserLogins = MySQLOAuthProvider2.getShareUsers(shareId); |
| 395 | + if(!groupUserLogins.contains(username)){ // the username of the one authorized != user that share was created for |
| 396 | + throw new PermissionDeniedException("401 Unauthorized"); |
| 397 | + } |
| 398 | + } // else share is open for everyone |
| 399 | + } |
| 400 | + |
| 401 | + MySQLOAuthProvider2.markAsAuthorized(reqToken, username); |
| 402 | + |
| 403 | + if(null != callbackUrl && !callbackUrl.isEmpty()){ |
| 404 | + if(callbackUrl.indexOf('?')<=0) |
| 405 | + callbackUrl += "?"+"oauth_token="+reqToken.getToken(); |
| 406 | + else |
| 407 | + callbackUrl += "&"+"oauth_token="+reqToken.getToken(); |
| 408 | + logger.debug("Redirecting user to "+callbackUrl); |
| 409 | + response.sendRedirect(callbackUrl); |
| 410 | + } else { |
| 411 | + response.setContentType("text/plain"); |
| 412 | + PrintWriter out = response.getWriter(); |
| 413 | + out.println("You have successfully authorized " |
| 414 | + + ".\nPlease close this browser window and click continue" |
| 415 | + + " in the client."); |
| 416 | + out.close(); |
| 417 | + } |
| 418 | + } catch (IOException e) { |
| 419 | + logger.error("Error performing the token authorization "+e.getMessage()); |
| 420 | + e.printStackTrace(); |
| 421 | + throw new Oops(e.getMessage()); |
| 422 | + } |
| 423 | + } |
302 | 424 |
|
303 | 425 | /** Initiate OpenID authentication. Return null if successful and no further action is necessary;
|
304 | 426 | * return an error message if there was a problem. */
|
@@ -330,6 +452,25 @@ private String initiateOpenid(HttpServletRequest request, HttpServletResponse re
|
330 | 452 | return null; // no errors
|
331 | 453 | }
|
332 | 454 |
|
| 455 | + private String initiateOA4MP(HttpServletRequest request, HttpServletResponse response) |
| 456 | + throws IOException |
| 457 | + { |
| 458 | + try { |
| 459 | + logger.debug("BEFORE FILE "); |
| 460 | + ClientEnvironment ce = ClientEnvironmentUtil.load(new File("/etc/vospace/client-cfg.xml")); |
| 461 | + logger.debug("READ FILE "); |
| 462 | + OA4MPService service = new OA4MPService(ce); |
| 463 | + logger.debug("OA4MP SERVICE"); |
| 464 | + OA4MPResponse oa4mpResponse = service.requestCert(); |
| 465 | + logger.debug("REDIRECTING TO: " + oa4mpResponse.getRedirect().toURL().toString()); |
| 466 | + response.sendRedirect(oa4mpResponse.getRedirect().toURL().toString()); |
| 467 | + } catch (Exception e) { |
| 468 | + logger.error("Exception during OA4MP initiation.", e); |
| 469 | + return "Unable to form OA4MP request: " + e.getMessage(); |
| 470 | + } |
| 471 | + return null; |
| 472 | + } |
| 473 | + |
333 | 474 | /** The URL to use for identityless authentication for a provider. Not all providers support it
|
334 | 475 | * -- we will need to do something fancier with discovery etc. for the general case, although
|
335 | 476 | * this will work fine with VAO SSO. */
|
@@ -358,4 +499,8 @@ private boolean isShareRequest(HttpServletRequest request) {
|
358 | 499 | private boolean isOpenIdResponse(HttpServletRequest request) {
|
359 | 500 | return !isBlank(request.getParameter("openid.ns"));
|
360 | 501 | }
|
| 502 | + |
| 503 | + private boolean isOA4MPResponse(HttpServletRequest request) { |
| 504 | + return !isBlank(request.getParameter("oauth_verifier")); |
| 505 | + } |
361 | 506 | }
|
0 commit comments