1 10 package org.mmbase.bridge.jsp.taglib; 11 12 import org.mmbase.bridge.jsp.taglib.util.Attribute; 13 import java.io.IOException ; 14 import java.io.File ; 15 16 import java.util.*; 17 18 import javax.servlet.http.*; 19 import javax.servlet.jsp.*; 20 import javax.servlet.RequestDispatcher ; 21 22 import org.mmbase.bridge.*; 23 import org.mmbase.bridge.ContextProvider; 24 import org.mmbase.security.*; import org.mmbase.util.functions.*; 26 27 28 import org.mmbase.util.StringSplitter; 29 30 import org.mmbase.util.logging.Logger; 31 import org.mmbase.util.logging.Logging; 32 33 43 44 public class CloudTag extends ContextReferrerTag implements CloudProvider, ParamHandler { 45 46 47 private static String INITIAL_REALM_PREFIX = "initial-"; 48 49 52 private static final String LOGINPAGE_COMMAND_PARAMETER = "command"; 53 private static final String LOGINPAGE_COMMAND_LOGIN = "login"; 54 private static final String LOGINPAGE_COMMAND_LOGOUT = "logout"; 55 private static final String LOGINPAGE_AUTHENTICATE_PARAMETER = "authenticate"; 56 private static final String LOGINPAGE_CLOUD_PARAMETER = "cloud"; 57 58 private static final String LOGINPAGE_DENYREASON_NEED = "please"; 59 private static final String LOGINPAGE_DENYREASON_FAIL = "failed"; 60 private static final String LOGINPAGE_DENYREASON_RANKTOOLOW = "rank"; 61 62 private static final int DENYREASON_FAIL = 1; 63 private static final int DENYREASON_RANKTOOLOW = 2; 64 65 private static final Logger log = Logging.getLoggerInstance(CloudTag.class); 66 67 private static final String DEFAULT_CLOUD_NAME = "mmbase"; 68 69 private static final String REALM = "realm_"; 70 71 72 private String jspVar; 73 74 private Cookie[] cookies; 75 76 private CloudContext cloudContext; 77 78 private Attribute cloudName = Attribute.NULL; 79 private Attribute cloudURI = Attribute.NULL; 80 private Cloud cloud; 81 82 85 private boolean sessionCloud = true; 86 87 private Attribute authenticate = Attribute.NULL; 88 89 private Attribute loginpage = Attribute.NULL; 90 91 private Attribute method = Attribute.NULL; 93 private Attribute logonatt = Attribute.NULL; 94 private List logon; 95 private Attribute pwd = Attribute.NULL; 96 private Attribute rank = Attribute.NULL; 97 private Attribute sessionName = Attribute.NULL; 98 99 private Attribute onfail = Attribute.NULL; 100 101 private HttpSession session; 102 private HttpServletRequest request; 103 private HttpServletResponse response; 104 private Locale locale; 105 106 109 public CloudContext getDefaultCloudContext() throws JspTagException { 110 if (cloudContext == null) { 111 cloudContext = ContextProvider.getCloudContext(cloudURI.getString(this)); 112 } 113 return cloudContext; 114 } 115 116 public void setUri(String uri) throws JspTagException { 117 cloudURI = getAttribute(uri); 118 } 119 120 public void setName(String name) throws JspTagException { 121 cloudName = getAttribute(name); 122 } 123 124 protected String getName() throws JspTagException { 125 if (cloudName == Attribute.NULL) { 126 return DEFAULT_CLOUD_NAME; 127 } 128 return cloudName.getString(this); 129 } 130 131 public void setLogon(String l) throws JspTagException { 132 logonatt = getAttribute(l); 133 } 134 public void setPwd(String pwd) throws JspTagException { 135 this.pwd = getAttribute(pwd); 136 } 137 138 141 public void setUsername(String l) throws JspTagException { 142 logonatt = getAttribute(l); 143 } 144 145 148 public void setPassword(String pwd) throws JspTagException { 149 this.pwd = getAttribute(pwd); 150 } 151 152 public void setRank(String r) throws JspTagException { 153 rank = getAttribute(r); 154 } 155 156 159 160 protected Rank getRank() throws JspTagException { 161 String s = rank.getString(this); 162 Rank r = Rank.getRank(s); 163 if (r == null) { 164 throw new JspTagException("Unknown rank '" + s + "'"); 165 } 166 return r; 167 } 168 169 172 public void setOnfail(String of) throws JspTagException { 173 onfail = getAttribute(of); 174 } 175 176 public void addParameter(String key, Object value) { 178 if (cloud != null) { 179 cloud.setProperty(key, value); 180 } 181 } 182 183 187 private boolean rankAnonymous() throws JspTagException { 188 if (rank == Attribute.NULL) { 189 return true; 190 } 191 String rankString = rank.getString(this); 192 return rankString.equals("") || rankString.equals(Rank.ANONYMOUS.toString()); 193 } 194 195 public void setJspvar(String jv) { 196 jspVar = jv; 197 } 198 199 public void setAuthenticate(String authenticate) throws JspTagException { 200 if (!"".equals(authenticate)) { this.authenticate = getAttribute(authenticate); 202 } else { 203 this.authenticate = Attribute.NULL; 204 } 205 } 206 207 protected String getAuthenticate() throws JspTagException { 208 String a = authenticate.getString(this); 209 if (a.equals("")) { 210 return cloudContext.getAuthentication().getTypes(getMethod())[0]; 211 } 212 return a; 213 } 214 215 public void setMethod(String mm) throws JspTagException { 216 method = getAttribute(mm); 217 } 218 219 protected int getMethod() throws JspTagException { 220 String m = method.getString(this); 221 int r = cloudContext.getAuthentication().getMethod(m); 222 if (log.isDebugEnabled()) { 223 log.debug("method '" + m + "' -> " + r); 224 } 225 return r; 226 } 227 228 232 protected int getMethodOrDefault() throws JspTagException { 233 int m = getMethod(); 234 if (m == AuthenticationData.METHOD_UNSET) { 235 if (! "".equals(loginpage.getString(this))) { 236 return AuthenticationData.METHOD_LOGINPAGE; 237 } else if (logonatt != Attribute.NULL && pwd != Attribute.NULL) { 238 return AuthenticationData.METHOD_SESSIONLOGON; 239 } else { 240 return cloudContext.getAuthentication().getDefaultMethod(request.getProtocol()); 241 } 242 } else { 243 return m; 244 } 245 } 246 247 public Cloud getCloudVar() { 248 return cloud; 249 } 250 251 public void setCloudVar(Cloud c) { 252 cloud = c; 253 } 254 255 public void setSessionname(String s) throws JspTagException { 256 if (!s.equals("")) { 257 sessionName = getAttribute(s); 258 } 259 } 260 261 public void setLoginpage(String loginpage) throws JspTagException { 262 this.loginpage = getAttribute(loginpage); 263 } 264 265 268 269 private Cookie searchCookie() throws JspTagException { 270 String cookie = REALM + getSessionName(); 271 if (log.isDebugEnabled()) { 272 log.debug("Searching cookie " + cookie); 273 } 274 if (cookies != null) { 275 for (int i = 0; i < cookies.length; i++) { 276 if (cookies[i].getName().equals(cookie) && (!"".equals(cookies[i].getValue()))) { 277 return cookies[i]; 278 } 279 } 280 } 281 log.debug("Cookie not found"); 282 return null; 283 } 284 285 290 private boolean setRealm(String r) throws JspTagException { 291 log.debug("setting realm in cookie"); 292 Cookie c = searchCookie(); 293 if (c == null) { 294 c = new Cookie(REALM + getSessionName(), r); 295 } else { 296 c.setValue(r); 297 } 298 String path = request.getContextPath(); 299 if (path.equals("")) path = "/"; 300 c.setPath(path); 301 c.setMaxAge((int) (60 * 60 * 24 * 365.25)); 303 if (cookies.length == 0) { 304 cookies = new Cookie[1]; 305 } 306 cookies[0] = c; 307 response.addCookie(c); 308 309 if (session != null) { 310 session.setAttribute(REALM + getSessionName(), r); 311 if (session.isNew()) { 312 log.debug("New session!? That is very suspicious. Perhaps URL was not encoded, and cookies disabled, sending redirect to make sure the url is encoded."); 313 String query = request.getQueryString(); 314 String thisPage = request.getRequestURI() + (query == null ? "" : "?" + query); 315 try { 316 String url = response.encodeRedirectURL(thisPage); 317 log.debug("Redirecting to " + url); 318 response.sendRedirect(url); 319 } catch (IOException e) { 320 throw new TaglibException(e); 321 } 322 } 323 324 if (log.isDebugEnabled()) { 325 log.debug("Setting realm " + r + " in session " + REALM + getSessionName()); 326 } 327 } 328 return true; 329 } 330 334 335 private void removeRealm() throws JspTagException { 336 log.debug("Removing realm"); 337 String currentRealm = getRealm(); 338 if (currentRealm != null && ! currentRealm.startsWith(INITIAL_REALM_PREFIX)) { String cookie = REALM + getSessionName(); 340 log.debug("removing cookie"); 341 if (cookies != null) { 342 for (int i = 0; i < cookies.length; i++) { 343 String path = request.getContextPath(); 344 if (path.equals("")) path = "/"; 345 if (cookies[i].getName().equals(cookie)) { 346 if (log.isDebugEnabled()) { 347 log.debug("removing cookie with value " + cookies[i]); 348 } 349 cookies[i].setValue(""); 350 cookies[i].setMaxAge(0); cookies[i].setPath(path); 352 response.addCookie(cookies[i]); 353 } 354 } 355 } 356 if (session != null) { 357 log.debug("Removing from session too"); 358 session.removeAttribute(REALM + getSessionName()); 359 } 360 } 361 } 362 365 private String getRealm() throws JspTagException { 366 Cookie c = searchCookie(); 367 if (c != null) { 368 if (log.isDebugEnabled()) { 369 log.debug("found cookie on path = " + c.getPath() + " -> " + c.getValue()); 370 } 371 return c.getValue(); 372 } 373 if (session != null) { 374 String realm = (String ) session.getAttribute(REALM + getSessionName()); 375 if (log.isDebugEnabled()) { 376 log.debug("Getting realm from session " + REALM + getSessionName() + " --> " + realm); 377 } 378 return realm; 379 } 380 return null; 381 } 382 383 384 private String getRealmName() { 385 String contextPath = request.getContextPath().replace('/', '_'); 386 return "MMBase" + contextPath + "@" + request.getServerName(); 387 } 388 389 398 private int denyHTTP(String message) throws JspTagException { 399 log.debug("sending deny"); 400 401 402 if (response.isCommitted()) { 403 throw new JspTagException("Response is commited already, cannot send a deny"); 404 } 405 406 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 407 408 String realm = getRealm(); 409 410 if (realm == null) { 411 realm = getRealmName(); 412 if (!setRealm(INITIAL_REALM_PREFIX + realm)) { 413 return SKIP_PAGE; 414 } 415 } else { 416 417 } 418 419 if (log.isDebugEnabled()) { 420 log.debug("Setting header WWW-Authenticate: " + realm); 421 } 422 response.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\""); 423 424 427 try { 431 ResourceBundle bundle = ResourceBundle.getBundle("org.mmbase.bridge.jsp.taglib.resources.messages", getLocale()); 432 pageContext.getOut().print("<h1 class=\"mm_cloud\">" + bundle.getString("cloudtag.fail") + "</h1><p class=\"mm_cloud\">" + message + "</p>"); 433 } catch (IOException ioe) { 434 throw new TaglibException(ioe); 435 } 436 setAnonymousCloud(); evalBody(); return SKIP_BODY; 439 } 440 441 private boolean setAnonymousCloud() throws JspTagException { 442 return setAnonymousCloud(null); 443 } 444 445 450 451 private boolean setAnonymousCloud(Parameters logoutInfo) throws JspTagException { 452 try { 453 if (log.isDebugEnabled()) { 456 log.debug("creating an anonymous cloud for cloud '" + getName() + "' (with " + logoutInfo + ")"); 457 } 458 if (logoutInfo != null) logoutInfo.checkRequiredParameters(); 460 cloud = getDefaultCloudContext().getCloud(getName(), "anonymous", logoutInfo == null ? null : logoutInfo.toMap()); 461 if (locale != null) { 462 cloud.setLocale(locale); 463 } 464 return true; 465 } catch (java.lang.SecurityException e) { 466 log.info("Could not create anonymous cloud because " + e.toString()); 468 cloud = null; 469 return false; 470 } catch (NotFoundException nfe) { 471 try { 472 if (!response.isCommitted()) { 473 response.setHeader("Retry-After", "60"); 474 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, nfe.getMessage()); 475 } 476 return false; 477 } catch (IOException ioe) { 478 throw new TaglibException(ioe); 479 } 480 } catch (Throwable t) { 481 throw new TaglibException("Could not create anonymous cloud because " + t.getClass().getName() + ": " + t.getMessage(), t); 482 } 483 } 484 485 486 public String getSessionName() throws JspTagException { 487 String sn = sessionName.getString(this); 488 if (sn.equals("")) { 489 return "cloud_" + getName(); 490 } else { 491 return sn; 492 } 493 } 494 495 499 500 private int evalBody() throws JspTagException { 501 502 if (getId() != null) { getContextProvider().getContextContainer().register(getId(), cloud); 504 } 505 506 if (cloud == null) { 507 return SKIP_BODY; 508 } 509 cloud.setProperty("request", request); 510 cloud.setProperty(LocaleTag.TZ_KEY, getTimeZone()); 511 512 if (jspVar != null) { 513 log.debug("Setting jspVar " + jspVar); 514 Object was = pageContext.getAttribute(jspVar); 515 if (was != null && ! was.equals(cloud)) { 516 throw new JspTagException("Jsp-var '" + jspVar + "' already in pagecontext! (" + was + "), can't write " + cloud + " in it. This may be a backwards-compatibility issue. This may be a backwards-compatibility issue. Change jspvar name or switch on backwards-compatibility mode (in your web.xml)"); 517 } 518 pageContext.setAttribute(jspVar, cloud); 519 } 520 521 if (locale != null) { 522 cloud.setLocale(locale); 523 } 524 525 getContextTag().setCloudContext(cloud.getCloudContext()); 527 528 ContentTag tag = (ContentTag) findParentTag(ContentTag.class, null, false); 529 if (tag != null) { 530 UserContext user = cloud.getUser(); 531 if (sessionCloud && ! user.getRank().equals(org.mmbase.security.Rank.ANONYMOUS)) { 532 tag.setUser(cloud.getUser()); 533 } 534 } 535 536 return EVAL_BODY; 537 } 538 539 546 547 private final boolean checkReuse() throws JspTagException { 548 if (getReferid() != null) { 549 int method = getMethod(); 550 if ((method != AuthenticationData.METHOD_UNSET && 551 method != AuthenticationData.METHOD_PAGELOGON && 552 method != AuthenticationData.METHOD_SESSIONLOGON) || 553 logonatt != Attribute.NULL) { throw new JspTagException("The 'referid' attribute of cloud cannot be used together with 'method' or 'logon' attributes"); 555 } 556 log.debug("found cloud with referid"); 557 cloud = (Cloud) getContextProvider().getContextContainer().getObject(getReferid()); 558 if (method == AuthenticationData.METHOD_SESSIONLOGON) { 559 session = request.getSession(true); 560 if (session == null) { 561 throw new JspTagException("No session, cannot store cloud in session"); 562 } 563 String sn = getSessionName(); 564 cloud.setProperty(Cloud.PROP_SESSIONNAME, sn); 565 session.setAttribute(sn, cloud); 566 } 567 return true; 568 } 569 return false; 570 } 571 572 576 577 private final boolean checkAnonymous() throws JspTagException { 578 try { 579 int m = getMethod(); 580 if ((m == AuthenticationData.METHOD_UNSET && logon == null && rankAnonymous() && loginpage == Attribute.NULL) || m == AuthenticationData.METHOD_ANONYMOUS) { log.debug("Implicitely requested anonymous cloud. Not using session"); 582 setAnonymousCloud(); 583 return true; 584 } else { 585 return false; 586 } 587 } catch (NotFoundException nfe) { 588 try { 589 if (!response.isCommitted()) { 590 response.setHeader("Retry-After", "60"); 591 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, nfe.getMessage()); 592 } 593 return true; 594 } catch (IOException ioe) { 595 throw new TaglibException(ioe); 596 } 597 } 598 } 599 600 603 private final boolean checkLogoutLoginPage() throws JspTagException { 604 if (loginpage != Attribute.NULL && LOGINPAGE_COMMAND_LOGOUT.equals(request.getParameter(LOGINPAGE_COMMAND_PARAMETER))) { 605 log.debug("request to log out, remove session atributes, give anonymous cloud."); 606 if (cloud != null) { 607 removeRealm(); 608 if (session != null) { 609 log.debug("ok. session is not null"); 610 session.removeAttribute(getSessionName()); } 612 } 613 setAnonymousCloud(); 614 return true; 615 } 616 return false; 617 } 618 619 622 private final boolean checkLogoutMethod() throws JspTagException { 623 if (getMethod() == AuthenticationData.METHOD_LOGOUT) { 624 log.debug("Requested logout"); 625 removeRealm(); 626 if (cloud != null) { 628 if (session != null) { 629 log.debug("ok. session is not null"); 630 session.removeAttribute(getSessionName()); } 632 } else { 633 log.debug("No cloud, so no need to log out"); 634 } 635 Parameters logoutInfo = cloudContext.getAuthentication().createParameters("anonymous"); 638 fillStandardParameters(logoutInfo); 639 if (cloud != null) { 640 String authenticate = cloud.getUser().getAuthenticationType(); 641 logoutInfo.setIfDefined(AuthenticationData.PARAMETER_AUTHENTICATE, authenticate); 642 } 643 logoutInfo.setIfDefined(AuthenticationData.PARAMETER_LOGOUT, Boolean.TRUE); 644 setAnonymousCloud(logoutInfo); 645 return true; 646 } else { 647 return false; 648 } 649 } 650 651 654 private final void setupSession() throws JspTagException { 655 cookies = request.getCookies(); 656 if (cookies == null) { 657 cookies = new Cookie[0]; 658 } 659 if (log.isDebugEnabled()) { 660 log.debug("getting (thus creating) session now: " + session); 661 } 662 session = request.getSession(false); 663 if (session != null) { String sessionName = getSessionName(); 665 Object c = session.getAttribute(sessionName); 666 if (c != null && ! (c instanceof Cloud)) { 667 throw new TaglibException("The session variable '" + sessionName + "' is not of type Cloud (but it is a '" + c.getClass().getName() + "'), and perhaps is used for another goal. This error could be avoided by use of the 'sessionname' attribute of the cloud-tag."); 668 } 669 cloud = (Cloud) c; 670 if (cloud != null) { 671 if (cloud.getUser().isValid()) { 672 if (log.isDebugEnabled()) { 673 log.debug("Created/found a session. Cloud '" + sessionName + "' in it is of: " + cloud.getUser()); 674 } 675 676 } else { 677 if (log.isDebugEnabled()) { 678 log.debug("Found invalid cloud in session variable '" + sessionName + "' of '" + cloud.getUser() + "'. Discarding."); 679 } 680 cloud = null; 681 } 682 } else { 683 log.debug("No cloud found in session variable '" + sessionName + "'"); 684 } 685 686 } else { 687 log.debug("Not succeeded creating a session"); 688 } 689 690 } 691 692 696 private final void checkLocale() throws JspTagException { 697 Locale l = getLocaleFromContext(); 698 if (l != null) { 700 locale = l; 701 } 702 } 703 704 705 709 710 private final boolean checkAsis() throws JspTagException { 711 if (getMethod() == AuthenticationData.METHOD_ASIS) { 712 session = request.getSession(false); 713 if (session != null) { 714 cloud = (Cloud) session.getAttribute(getSessionName()); 715 } 716 if (cloud == null) { 717 setAnonymousCloud(); 718 } 719 if (cloud != null) { 720 checkValid(); 721 } 722 checkCloud(); 723 return true; 724 } 725 return false; 726 727 } 728 729 732 733 private final void checkValid() { 734 if (!cloud.getUser().isValid()) { 735 log.debug("found a cloud in the session, but is was expired, throwing it away"); 736 cloud = null; 737 } 738 } 739 740 743 private final void removeCloud() throws JspTagException { 744 cloud = null; 745 if (session != null) { 746 session.removeAttribute(getSessionName()); 747 } 748 } 749 750 755 private final void checkCloud() throws JspTagException { 756 757 if (cloud == null) { 758 log.debug("Cloud is null, cannot check it"); 759 removeCloud(); 760 return; 761 } 762 if (log.isDebugEnabled()) { 765 log.debug("found cloud m: " + method + " l: " + logon + ". Checking it."); 766 } 767 if (cloud.getUser() == null) { 768 log.debug("found a cloud in the session, but is has no user, throwing it away"); 769 removeCloud(); 770 return; 771 } 772 773 774 if (!cloud.getUser().isValid()) { 775 log.debug("found a cloud in the session, but is was expired, throwing it away"); 781 removeCloud(); 782 return; 783 } 784 785 int meth = getMethod(); 786 if (logon == null && rank == Attribute.NULL && meth != AuthenticationData.METHOD_UNSET && meth != AuthenticationData.METHOD_ASIS) { 787 if (log.isDebugEnabled()) { 789 log.debug("Implicitily requested non-anonymous (by method) cloud. Current user: " + cloud.getUser().getIdentifier()); 790 } 791 if (cloud.getUser().getRank().equals(Rank.ANONYMOUS)) { log.debug("there was a cloud, but anonymous. log it on"); 793 removeCloud(); 794 return; 795 } 796 797 } else if (logon != null && cloud != null) { 798 if (log.isDebugEnabled()) { 799 log.debug("Explicitily requested non-anonymous cloud (by logon = '" + logon + "'). Current user: " + cloud.getUser().getIdentifier()); 800 } 801 if (!logon.contains(cloud.getUser().getIdentifier())) { log.debug("logged on, but as wrong user. log out first."); 804 removeCloud(); 805 return; 806 } else { 807 log.debug("Cloud is ok already"); 808 } 809 } 810 if (!rankAnonymous()) { 811 if (log.isDebugEnabled()) { 812 log.debug("Explicitily requested non-anonymous cloud (by rank). Current user: " + cloud.getUser()); 813 } 814 Rank curRank = cloud.getUser().getRank(); 815 if (curRank.getInt() < getRank().getInt()) { 816 if (log.isDebugEnabled()) { 817 log.debug("logged on, but rank of user (" + curRank.toString() + ") is too low (must be " + getRank().toString() + "). log out first."); 818 } 819 removeCloud(); 820 return; 821 } else { 822 log.debug("Cloud is ok already"); 823 } 824 825 } 826 if (meth != AuthenticationData.METHOD_UNSET && 827 meth != AuthenticationData.METHOD_ASIS && 828 cloud != null && 829 authenticate != Attribute.NULL && 830 (!cloud.getUser().getAuthenticationType().equals(getAuthenticate()))) { 831 log.debug("Cloud was logged on with different authentication type ('" + cloud.getUser().getAuthenticationType() 832 + "' in stead of the requested '" + getAuthenticate() + "'. Should do procedure again."); 833 removeCloud(); 834 return; 835 } else { 836 log.debug("Cloud was logged with same authentication type -> ok"); 837 } 838 839 } 840 841 847 848 private final int doHTTPAuthentication(Parameters user) throws JspTagException { 849 log.debug("with http"); 850 ResourceBundle bundle = ResourceBundle.getBundle("org.mmbase.bridge.jsp.taglib.resources.messages", getLocale()); 851 852 String realm = getRealm(); 853 if (realm == null ) { 854 log.debug("no realm found, need to log on again"); 855 return denyHTTP("<h2 class=\"mm_cloud\">" + bundle.getString("cloudtag.again") + "</h2><p class=\"mm_cloud\">" + bundle.getString("cloudtag.logout") + "</p>"); 856 } 857 if (realm.startsWith(INITIAL_REALM_PREFIX)) { 858 realm = realm.substring(INITIAL_REALM_PREFIX.length()); 859 if (! setRealm(realm)) { 860 return SKIP_PAGE; 861 } 862 } 863 String mime_line = request.getHeader("Authorization"); 864 if (log.isDebugEnabled()) { 865 log.debug("authent: " + request.getHeader("WWW-Authenticate") + " realm: " + realm + " authorization " + mime_line); 866 } 867 String userName = null; 869 String password = null; 870 try { 871 if (mime_line != null) { 872 String user_password = org.mmbase.util.Encode.decode("BASE64", mime_line.substring(6)); 873 StringTokenizer t = new StringTokenizer(user_password, ":"); 874 if (t.countTokens() == 2) { 875 userName = t.nextToken(); 876 password = t.nextToken(); 877 } 878 } 879 } catch (Exception e) { 880 log.error(e); 881 } 882 if (log.isDebugEnabled()) { 884 log.debug("u " + userName + " p " + password); 885 } 886 887 if (logon != null) { log.debug("http with username"); 889 if (!logon.contains(userName)) { 890 log.debug("username not correct"); 891 return denyHTTP("<h2 class=\"mm_cloud\">" + bundle.getString("cloudtag.wronguser") + "</h2><p class\"mm_cloud\">" + bundle.getString("cloudtag.mustbe") + logon + "</p>"); 892 } else { 893 logon = new ArrayList(); 894 logon.add(userName); 895 } 896 } else { log.debug("http without username"); 898 if (userName == null) { log.debug("no username known"); 900 return denyHTTP("<h2 class=\"mm_cloud\">" + bundle.getString("cloudtag.nouser") + "</h2>"); 901 } 902 906 } 907 user.set(AuthenticationData.PARAMETER_USERNAME, userName); 908 user.set(AuthenticationData.PARAMETER_PASSWORD, password); 909 return EVAL_BODY; 910 911 } 912 913 914 915 916 923 924 private int doLoginPage(Parameters user) throws JspTagException { 925 log.debug("login page required to acces this cloud data!"); 926 927 if (LOGINPAGE_COMMAND_LOGIN.equals(request.getParameter(LOGINPAGE_COMMAND_PARAMETER))) { 930 931 if (log.isDebugEnabled()) { 932 log.debug("Request to login with loginpage, trying to perform an login"); 933 } 934 String authenticatePassed = request.getParameter(LOGINPAGE_AUTHENTICATE_PARAMETER); 936 if (authenticatePassed != null) { 937 setAuthenticate(authenticatePassed); } 939 String cloudNamePassed = request.getParameter(LOGINPAGE_CLOUD_PARAMETER); 940 if (cloudNamePassed != null) { 941 setName(cloudNamePassed); } 943 user.setAutoCasting(true); 944 Enumeration enumeration = request.getParameterNames(); 945 while (enumeration.hasMoreElements()) { 946 String key = (String ) enumeration.nextElement(); 947 String value = (String ) org.mmbase.bridge.jsp.taglib.util.ContextContainer.fixEncoding(request.getParameter(key), pageContext); 948 if (log.isDebugEnabled()) { 949 log.debug("security info --> key:" + key + " value:" + value); 950 } 951 user.setIfDefined(key, value); 952 } 953 fillStandardParameters(user); 954 return EVAL_BODY; 955 } else { 956 return denyLoginPage(LOGINPAGE_DENYREASON_NEED, ""); 958 } 959 } 960 961 967 private int denyLoginPage(String reason, String exactReason) throws JspTagException { 968 log.debug("Denying to login-page"); 969 try { 970 971 String referrerPage = null; 973 974 String requestURI = request.getRequestURI(); 975 if (requestURI.endsWith("/")) { 976 referrerPage = "."; 977 } else { 978 referrerPage = new File (requestURI).getName(); 979 } 980 981 982 1007 1008 1009 1010 String toFile = loginpage.getString(this); 1011 1012 String referrer = null; 1013 1014 int existingQueryPosition = toFile.indexOf('?'); 1016 if (existingQueryPosition > 0) { 1017 String existingQuery = toFile.substring(existingQueryPosition + 1); 1018 log.debug("Found existing query " + existingQuery); 1019 String [] parameters = existingQuery.split("&"); 1020 for (int i = 0; i < parameters.length; i++) { 1021 if (parameters[i].startsWith("referrer=")) { 1022 referrer = org.mmbase.util.Encode.decode("escape_url", parameters[i].substring(9)); 1023 if (referrer.startsWith("?")) referrer = "." + referrer; log.debug("Found existing referrer " + referrer); 1025 break; 1026 } 1027 } 1028 } 1029 if (referrer == null) { 1030 if (request.getQueryString() != null) { 1031 referrer = referrerPage + "?" + request.getQueryString(); 1032 } else { 1033 referrer = referrerPage; 1034 } 1035 } 1036 log.debug("Using " + referrer); 1037 if (! response.isCommitted()) { 1038 RequestDispatcher rd = request.getRequestDispatcher(toFile); 1040 request.setAttribute("referrerpage", referrerPage); 1041 request.setAttribute("referrer", referrer); 1042 request.setAttribute("reason", reason); 1043 request.setAttribute("exactreason", exactReason); 1044 request.setAttribute("usernames", logon); 1045 rd.forward(request, response); 1046 } 1047 return SKIP_BODY; 1048 } catch (javax.servlet.ServletException ioe) { 1049 throw new TaglibException("error sending redirect", ioe); 1050 } catch (java.io.IOException ioe) { 1051 throw new TaglibException("error sending redirect", ioe); 1052 } 1053 } 1054 1055 private final int deny(int reason, String exactReason) throws JspTagException { 1056 int meth = getMethodOrDefault(); 1057 switch(meth){ 1059 case AuthenticationData.METHOD_HTTP: ResourceBundle bundle = ResourceBundle.getBundle("org.mmbase.bridge.jsp.taglib.resources.messages", getLocale()); 1061 switch (reason) { 1062 case DENYREASON_RANKTOOLOW : 1063 return denyHTTP("<h2 class=\"mm_cloud\">" + bundle.getString("cloudtag.ranktoolow") + " (" + bundle.getString("cloudtag.mustbeatleast") + getRank().toString() + ")</h2>"); 1064 case DENYREASON_FAIL : 1065 default : 1066 return denyHTTP("<h2 class=\"mm_cloud\">" + bundle.getString("cloudtag.authentication") + "</h2>"); 1067 } 1068 case AuthenticationData.METHOD_LOGINPAGE: 1069 switch (reason) { 1070 case DENYREASON_RANKTOOLOW : 1071 return denyLoginPage(LOGINPAGE_DENYREASON_RANKTOOLOW, exactReason); 1072 case DENYREASON_FAIL : 1073 default : 1074 return denyLoginPage(LOGINPAGE_DENYREASON_FAIL, exactReason); 1075 } 1076 case AuthenticationData.METHOD_DELEGATE: 1077 case AuthenticationData.METHOD_SESSIONDELEGATE: 1078 switch (reason) { 1079 case DENYREASON_RANKTOOLOW : 1080 case DENYREASON_FAIL : 1082 default : 1083 return SKIP_BODY; 1084 } 1085 default: 1086 switch (reason) { 1088 case DENYREASON_FAIL : { 1089 if ("name/password".equals(getAuthenticate())) { 1090 throw new JspTagException("Logon of with " 1091 + (logon != null && logon.size() > 0 ? "'" + logon.get(0) + "'" : "''") 1092 + " failed." 1093 + (pwd == Attribute.NULL ? " (no password given)" : " (wrong password)")); 1094 } else { 1095 throw new JspTagException("Authentication ('" + getAuthenticate() + "') failed"); 1096 } 1097 } 1098 case DENYREASON_RANKTOOLOW : { 1099 throw new JspTagException("Rank too low"); 1100 } 1101 default : 1102 throw new JspTagException("Denied for unknown reason"); 1103 } 1104 } 1105 } 1106 1107 1113 private final int doLogin(Parameters user) throws JspTagException { 1114 log.debug("Username found. logging in"); 1115 try { 1116 user.checkRequiredParameters(); 1117 cloud = getDefaultCloudContext().getCloud(getName(), getAuthenticate(), user == null ? null : user.toMap()); 1118 log.debug("Logged in " ); 1119 if (!cloud.getUser().isValid()) { 1120 log.warn("Just acquired user " + cloud.getUser().getIdentifier() + " is not valid!"); 1121 return deny(DENYREASON_FAIL, "Just acquired user " + cloud.getUser().getIdentifier() + " is not valid!"); 1122 } 1123 if (rank != Attribute.NULL) { 1125 log.debug("Checking for rank"); 1126 Rank curRank = cloud.getUser().getRank(); 1127 if (curRank == null) { 1128 throw new RuntimeException ("The user " + cloud.getUser() + " had rank 'null'"); 1129 } 1130 Rank r = getRank(); 1131 if (curRank.getInt() < r.getInt()) { 1132 if (log.isDebugEnabled()) { 1133 log.debug("logged on, but rank of user is too low (" + cloud.getUser().getRank() + ". log out first."); 1134 } 1135 cloud = null; 1136 if (session != null) { 1137 session.removeAttribute(getSessionName()); 1138 } 1139 log.debug("rank too low"); 1140 return deny(DENYREASON_RANKTOOLOW, "" + curRank + " < " + r); 1141 } 1142 } 1143 return EVAL_BODY; 1144 } catch (java.lang.SecurityException e) { 1145 if (log.isDebugEnabled()) { 1146 log.debug("Failed to log in with " + user + " because " + e.toString()); 1147 } 1148 return deny(DENYREASON_FAIL, e.getMessage()); 1149 } 1150 } 1151 1152 1156 1157 private final int makeCloud() throws JspTagException { 1158 Parameters user = null; 1159 int meth = getMethodOrDefault(); 1160 if (log.isDebugEnabled()) { 1161 log.debug("Creating the cloud with method " + meth); 1162 } 1163 1164 switch(meth) { 1166 1167 case AuthenticationData.METHOD_SESSIONDELEGATE: 1168 case AuthenticationData.METHOD_DELEGATE: 1169 if (log.isDebugEnabled()) { 1170 log.debug("delegate for " + getAuthenticate()); 1171 } 1172 user = cloudContext.getAuthentication().createParameters(getAuthenticate()); 1173 if (logon != null) { 1174 user.setIfDefined(AuthenticationData.PARAMETER_USERNAMES, logon); 1175 } 1176 if (rank != Attribute.NULL) { 1177 user.setIfDefined(AuthenticationData.PARAMETER_RANK, getRank()); 1178 } 1179 sessionCloud = meth == AuthenticationData.METHOD_SESSIONDELEGATE; 1180 break; 1181 case AuthenticationData.METHOD_HTTP: 1182 log.debug("http"); 1183 user = cloudContext.getAuthentication().createParameters(getAuthenticate()); 1184 sessionCloud = true; 1185 if (doHTTPAuthentication(user) == SKIP_BODY) { 1186 return SKIP_BODY; 1187 } 1188 break; 1189 case AuthenticationData.METHOD_LOGINPAGE: 1190 log.debug("loginpage for " + getAuthenticate()); 1191 user = cloudContext.getAuthentication().createParameters(getAuthenticate()); 1192 sessionCloud = true; 1193 if (doLoginPage(user) == SKIP_BODY) { 1194 return SKIP_BODY; 1195 } 1196 break; 1197 default: 1198 log.debug("default"); 1199 if (logon != null && pwd != Attribute.NULL) { 1200 user = cloudContext.getAuthentication().createParameters(getAuthenticate()); 1201 user.set(AuthenticationData.PARAMETER_USERNAME, logon.get(0)); 1202 user.set(AuthenticationData.PARAMETER_PASSWORD, pwd.getString(this)); 1203 if (meth == AuthenticationData.METHOD_PAGELOGON) { 1204 sessionCloud = false; 1205 } else { 1206 if (meth != AuthenticationData.METHOD_SESSIONLOGON) { 1207 log.warn("Using logon/pwd (or username/password) attributes on page '" + request.getRequestURI() + "' without specifying method='[pagelogon|sessionlogon]', defaulting to 'sessionlogon'. Be aware that users of this page now are authenticated in their session!"); 1208 } 1209 sessionCloud = true; 1210 } 1211 } else { 1212 sessionCloud = false; 1213 } 1214 } 1215 1216 if (user != null) { 1218 fillStandardParameters(user); 1219 if (doLogin(user) == SKIP_BODY) { 1220 return SKIP_BODY; 1221 } 1222 } else { 1223 log.debug("no login given, creating anonymous cloud"); 1224 setAnonymousCloud(); 1226 } 1227 checkCloud(); if (cloud == null) { 1235 1236 log.debug("Could not create Cloud."); 1237 return SKIP_BODY; 1239 } else { 1240 if (sessionCloud) { 1241 if (session == null) session = request.getSession(true); 1242 if (session != null) { 1243 String sn = getSessionName(); 1244 cloud.setProperty(Cloud.PROP_SESSIONNAME, sn); 1245 log.debug("Setting cloud in session variable '" + sn + "'"); 1246 session.setAttribute(sn, cloud); 1247 } 1248 } else { 1249 log.debug("Not storing cloud because session: " + (session != null) + " put cloud " + sessionCloud); 1250 } 1251 } 1252 return EVAL_BODY; 1253 } 1254 1255 1258 1259 public void setPageContext(PageContext pc) { 1260 super.setPageContext(pc); 1261 request = (HttpServletRequest) pageContext.getRequest(); 1262 response = (HttpServletResponse) pageContext.getResponse(); 1263 if (log.isDebugEnabled()) { 1264 log.debug("Got a " + response.getClass().getName() + " (commited: " + response.isCommitted() + ")"); 1265 } 1266 } 1267 1268 1269 1273 public int doStartTag() throws JspTagException { 1274 checkLocale(); 1276 1277 { 1278 String s = logonatt.getString(this); 1279 logon = s.equals("") ? null : StringSplitter.split(s); 1280 } 1281 1282 getDefaultCloudContext(); 1283 if (checkReuse()) { return evalBody(); 1285 } 1286 if (checkAnonymous()) { if (cloud == null) { return SKIP_BODY; 1290 } else { 1291 log.debug("Implicitely requested anonymous cloud. Will not use session"); 1293 return evalBody(); 1294 } 1295 } 1296 if (checkAsis()) { if (cloud == null) { return SKIP_BODY; 1299 } else { 1300 return evalBody(); 1301 } 1302 } 1303 setupSession(); if (log.isDebugEnabled()) { 1305 log.debug("startTag " + cloud); 1306 } 1307 if (checkLogoutLoginPage()) { 1308 try { 1310 String url = request.getRequestURI(); 1311 response.sendRedirect(url); 1312 } catch (java.io.IOException ioe) { 1313 throw new TaglibException(ioe); 1314 } 1315 return SKIP_BODY; 1316 } 1317 if (checkLogoutMethod()) { 1318 return evalBody(); 1319 } 1320 1321 if (cloud != null) { 1322 checkCloud(); 1323 } 1324 if (cloud == null) { 1325 if (makeCloud() == SKIP_BODY) { return SKIP_BODY; 1327 } 1328 } 1329 1331 return evalBody(); 1332 } 1333 1334 public int doEndTag() throws JspTagException { 1335 return super.doEndTag(); 1336 } 1337 1338 public void doFinally() { 1339 super.doFinally(); 1341 cookies = null; 1342 cloudContext = null; 1343 cloud = null; 1344 logon = null; 1345 session = null; 1346 request = null; 1347 response = null; 1348 } 1349 1350 public int doAfterBody() throws JspTagException { 1352 1353 if (EVAL_BODY == EVAL_BODY_BUFFERED) { 1354 try { 1355 if (bodyContent != null) { 1356 bodyContent.writeOut(bodyContent.getEnclosingWriter()); 1357 } 1358 } catch (IOException ioe) { 1359 throw new TaglibException(ioe); 1360 } 1361 } 1362 return SKIP_BODY; 1363 } 1364 1365} 1366 | Popular Tags |