001/* 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: AssertionManager.java,v 1.13 2010/01/09 19:41:06 qcheng Exp $ 026 * 027 * Portions Copyrighted 2013-2015 ForgeRock AS. 028 */ 029 030package com.sun.identity.saml; 031 032import java.util.Map; 033import java.util.HashMap; 034import java.util.Date; 035import java.util.List; 036import java.util.ArrayList; 037import java.util.Set; 038import java.util.HashSet; 039import java.util.Iterator; 040import java.net.InetAddress; 041import org.w3c.dom.Element; 042import com.sun.identity.common.GeneralTaskRunnable; 043import com.sun.identity.common.PeriodicGroupRunnable; 044import com.sun.identity.common.ScheduleableGroupAction; 045import com.sun.identity.common.SystemTimerPool; 046import com.sun.identity.common.TaskRunnable; 047import com.sun.identity.common.TimerPool; 048import com.sun.identity.saml.assertion.*; 049import com.sun.identity.saml.protocol.*; 050import com.sun.identity.saml.common.*; 051import com.sun.identity.saml.plugins.*; 052import com.sun.identity.saml.xmlsig.*; 053import com.sun.identity.shared.Constants; 054import com.sun.identity.shared.DateUtils; 055import com.sun.identity.common.SystemConfigurationUtil; 056import com.sun.identity.shared.encode.Base64; 057import com.sun.identity.shared.stats.Stats; 058import com.sun.identity.shared.xml.XMLUtils; 059import java.util.StringTokenizer; 060import com.sun.identity.plugin.monitoring.FedMonAgent; 061import com.sun.identity.plugin.monitoring.FedMonSAML1Svc; 062import com.sun.identity.plugin.monitoring.MonitorManager; 063import com.sun.identity.plugin.session.SessionException; 064import com.sun.identity.plugin.session.SessionManager; 065import com.sun.identity.plugin.session.SessionProvider; 066import javax.servlet.http.HttpServletRequest; 067import javax.servlet.http.HttpServletResponse; 068 069/** 070 * The class <code>AssertionManager</code> is a <code>final</code> class 071 * that provides interfaces to create, get and destroy <code>Assertion</code>s. 072 * <p> 073 * It is a singleton class; an instance of this class can be obtained by 074 * calling <code>AssertionManager.getInstance()</code>. 075 * <p> 076 * Having obtained an instance of <code>AssertionManager</code>, its methods 077 * can be called to create/get <code>Assertion</code>, and 078 * <code>AssertionArtifact</code>, and to obtain decision from an 079 * <code>Query</code>. 080 * <p> 081 * This class could only be used in the same JVM as OpenAM. 082 * @supported.api 083 */ 084public final class AssertionManager { 085 086 // General stats class 087 public static Stats assStats; 088 public static Stats artStats; 089 090 // Assertion Statistics Class 091 private static AssertionStats assertionStats; 092 093 // Artifact Statistics Class 094 private static ArtifactStats artifactStats; 095 096 private static final String SUPER_USER = 097 "com.sun.identity.authentication.super.user"; 098 private static String superUser = null; 099 private static SessionProvider sessionProvider = null; 100 101 private static long cleanUpInterval; 102 private static long assertionTimeout; 103 private static long artifactTimeout; 104 private static long notBeforeSkew; 105 106 private static FedMonAgent agent; 107 private static FedMonSAML1Svc saml1Svc; 108 109 static { 110 assStats = Stats.getInstance("amAssertionMap"); 111 artStats = Stats.getInstance("amArtifactMap"); 112 superUser = SystemConfigurationUtil.getProperty(SUPER_USER); 113 try { 114 sessionProvider = SessionManager.getProvider(); 115 } catch (SessionException se) { 116 SAMLUtils.debug.error("Static: Couldn't get SessionProvider.", 117 se); 118 sessionProvider = null; 119 } 120 cleanUpInterval = ((Integer) SAMLServiceManager.getAttribute( 121 SAMLConstants.CLEANUP_INTERVAL_NAME)).intValue() * 1000; 122 artifactTimeout = ((Integer) SAMLServiceManager.getAttribute( 123 SAMLConstants.ARTIFACT_TIMEOUT_NAME)).intValue() * 1000; 124 assertionTimeout = ((Integer) SAMLServiceManager.getAttribute( 125 SAMLConstants.ASSERTION_TIMEOUT_NAME)).intValue() * 1000; 126 notBeforeSkew = ((Integer) SAMLServiceManager.getAttribute( 127 SAMLConstants.NOTBEFORE_TIMESKEW_NAME)).intValue() * 1000; 128 129 agent = MonitorManager.getAgent(); 130 saml1Svc = MonitorManager.getSAML1Svc(); 131 } 132 133 // Singleton instance of AssertionManager 134 private static AssertionManager instance = null; 135 136 // used to store artifact to assertionID mapping 137 private static Map artEntryMap = null; 138 // used to store assertionIDString to entry mapping 139 private static Map idEntryMap = null; 140 141 private static TaskRunnable assertionTimeoutRunnable; 142 private static TaskRunnable artifactTimeoutRunnable; 143 private static TaskRunnable goThroughRunnable; 144 145 private static String assertionVersion = null; 146 private static String protocolVersion = null; 147 148 149 private class Entry { 150 private String destID = null; 151 private String artString = null; 152 private Object token = null; 153 private Assertion assertion = null; 154 155 public Entry(Assertion assertion, String destID, String artString, 156 Object token) 157 { 158 this.assertion = assertion; 159 this.destID = destID; 160 this.artString = artString; 161 this.token = token; 162 } 163 164 public Assertion getAssertion() { 165 return assertion; 166 } 167 168 public String getDestID() { 169 return destID; 170 } 171 172 public void setDestID(String newDestID) { 173 destID = newDestID; 174 } 175 176 public String getArtifactString() { 177 return artString; 178 } 179 180 public void setArtifactString(String newArtifactString) { 181 artString = newArtifactString; 182 } 183 184 public Object getSSOToken() { 185 return token; 186 } 187 } 188 189 private class ArtEntry { 190 private String aID = null; 191 private long expiretime = 0; 192 193 public ArtEntry(String aID, long expiretime) { 194 this.aID = aID; 195 this.expiretime = expiretime; 196 } 197 198 public String getAssertionID() { 199 return aID; 200 } 201 202 public long getExpireTime() { 203 return expiretime; 204 } 205 } 206 207 /** 208 * Default Constructor 209 */ 210 private AssertionManager() { 211 idEntryMap = new HashMap(); 212 artEntryMap = new HashMap(); 213 try { 214 assertionVersion = SystemConfigurationUtil.getProperty( 215 SAMLConstants.SAML_ASSERTION_VERSION); 216 protocolVersion = SystemConfigurationUtil.getProperty( 217 SAMLConstants.SAML_PROTOCOL_VERSION); 218 } catch (Exception e) { 219 assertionVersion = SAMLConstants.ASSERTION_VERSION_1_0; 220 protocolVersion = SAMLConstants.PROTOCOL_VERSION_1_0; 221 } 222 TimerPool timerPool = SystemTimerPool.getTimerPool(); 223 ScheduleableGroupAction assertionTimeoutAction = new 224 ScheduleableGroupAction() { 225 public void doGroupAction(Object obj) { 226 deleteAssertion((String) obj, null); 227 } 228 }; 229 230 assertionTimeoutRunnable = new PeriodicGroupRunnable( 231 assertionTimeoutAction, cleanUpInterval, assertionTimeout, true); 232 timerPool.schedule(assertionTimeoutRunnable, new Date((( 233 System.currentTimeMillis() + cleanUpInterval) / 1000) * 1000)); 234 235 ScheduleableGroupAction artifactTimeoutAction = new 236 ScheduleableGroupAction() { 237 public void doGroupAction(Object obj) { 238 deleteAssertion(null, (String) obj); 239 } 240 }; 241 242 artifactTimeoutRunnable = new PeriodicGroupRunnable( 243 artifactTimeoutAction, cleanUpInterval, artifactTimeout, true); 244 245 timerPool.schedule(artifactTimeoutRunnable, new Date((( 246 System.currentTimeMillis() + cleanUpInterval) / 1000) * 1000)); 247 248 goThroughRunnable = new GoThroughRunnable(cleanUpInterval); 249 250 timerPool.schedule(goThroughRunnable, new Date((( 251 System.currentTimeMillis() + cleanUpInterval) / 1000) * 1000)); 252 253 if (assStats.isEnabled()) { 254 artifactStats = new ArtifactStats(artEntryMap); 255 artStats.addStatsListener(artifactStats); 256 assertionStats = new AssertionStats(idEntryMap); 257 assStats.addStatsListener(assertionStats); 258 } 259 260 } 261 262 /** 263 * Gets the singleton instance of <code>AssertionManager</code>. 264 * @return The singleton <code>AssertionManager</code> instance 265 * @throws SAMLException if unable to get the singleton 266 * <code>AssertionManager</code> instance. 267 * @supported.api 268 */ 269 public static AssertionManager getInstance() throws SAMLException { 270 // not throwing any exception 271 if (instance == null) { 272 synchronized (AssertionManager.class) { 273 if (instance == null) { 274 if (SAMLUtils.debug.messageEnabled() ) { 275 SAMLUtils.debug.message("Constructing a new instance" 276 + " of AssertionManager"); 277 } 278 instance = new AssertionManager(); 279 } 280 } 281 } 282 return instance; 283 } 284 285 /** 286 * This method creates an Assertion that contains an 287 * <code>AuthenticationStatement</code>. 288 * @param token user's session object that contains authentication 289 * information which is needed to create the 290 * <code>AuthenticationStatement</code>. 291 * @return Assertion The created Assertion. 292 * @throws SAMLException If the Assertion cannot be created. 293 * @supported.api 294 */ 295 public Assertion createAssertion(Object token) 296 throws SAMLException 297 { 298 if (assertionVersion.equals(SAMLConstants.ASSERTION_VERSION_1_0)) { 299 return createAssertion(token, null, 300 SAMLConstants.DEPRECATED_CONFIRMATION_METHOD_ARTIFACT, 0); 301 } else if(assertionVersion.equals( 302 SAMLConstants.ASSERTION_VERSION_1_1)) { 303 return createAssertion(token, null, 304 SAMLConstants.CONFIRMATION_METHOD_ARTIFACT, 1); 305 } else { 306 throw new SAMLException(SAMLUtils.bundle.getString( 307 "assertionVersionNotSupport")); 308 } 309 } 310 311 /** 312 * This method creates an Assertion that contains an 313 * <code>AuthenticationStatement</code> and 314 * an <code>AttributeStatement</code>. 315 * @param token User' session object that contains authentication 316 * information which is needed to create the 317 * <code>AuthenticationStatement</code> for the Assertion. 318 * @param attributes A list of Attribute objects which are used to 319 * create the <code>AttributeStatement</code> for the Assertion. 320 * @return Assertion The created Assertion. 321 * @throws SAMLException If the Assertion cannot be created. 322 * @supported.api 323 */ 324 public Assertion createAssertion(Object token, List attributes) 325 throws SAMLException 326 { if (assertionVersion.equals(SAMLConstants.ASSERTION_VERSION_1_0)) { 327 return createAssertion(token, attributes, 328 SAMLConstants.DEPRECATED_CONFIRMATION_METHOD_ARTIFACT, 0); 329 } else if (assertionVersion.equals( 330 SAMLConstants.ASSERTION_VERSION_1_1)) { 331 return createAssertion(token, attributes, 332 SAMLConstants.CONFIRMATION_METHOD_ARTIFACT, 1); 333 } else { 334 throw new SAMLException(SAMLUtils.bundle.getString( 335 "assertionVersionNotSupport")); 336 } 337 } 338 339 private Assertion createAssertion(Object token, List attributes, 340 String confirmationMethod, int minorVersion) 341 throws SAMLException 342 { 343 if (token == null) { 344 SAMLUtils.debug.error("AssertionManager.createAssertion(id):" 345 + "input Session is null."); 346 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 347 } 348 if (sessionProvider == null) { 349 throw new SAMLException(SAMLUtils.bundle.getString( 350 "nullSessionProvider")); 351 } 352 String id = sessionProvider.getSessionID(token); 353 return createAssertion(id, null, null, attributes, 354 confirmationMethod, minorVersion, null); 355 } 356 357 /** 358 * This method creates an <code>AssertionArtifact</code> for the given 359 * Assertion. 360 * 361 * @param assertion The Assertion for which an Artifact needs to be created. 362 * @param destID The <code>sourceID</code> of the site for which the 363 * <code>AssertionArtifact</code> is created. It is in raw String 364 * format (not Base64 encoded, for example.) This String can be 365 * obtained from converting the 20 bytes sequence to char Array, then 366 * from the char Array to String. 367 * @return <code>AssertionArtifact</code> 368 * @throws SAMLException If the <code>AssertionArtifact</code> cannot be 369 * created. 370 * @supported.api 371 */ 372 public AssertionArtifact createAssertionArtifact(Assertion assertion, 373 String destID) 374 throws SAMLException 375 { 376 if ((assertion == null) || (destID == null) || (destID.length() == 0)) { 377 SAMLUtils.debug.error("AssertionManager.createAssertionArti" 378 + "fact(Assertion, String): null input."); 379 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 380 } 381 382 Map partner = (Map) SAMLServiceManager.getAttribute( 383 SAMLConstants.PARTNER_URLS); 384 if ((partner == null) || (!partner.containsKey(destID))) { 385 SAMLUtils.debug.error("AssertionManager.createAssertionArtifact:" + 386 "(Assertion, String): destID not in partner list."); 387 throw new SAMLException( 388 SAMLUtils.bundle.getString("destIDNotFound")); 389 } 390 391 String handle = SAMLUtils.generateAssertionHandle(); 392 if (handle == null) { 393 SAMLUtils.debug.error("AssertionManager.createAssertion" 394 + "Artifact(Assertion,String): couldn't generate " 395 + "assertion handle."); 396 throw new SAMLResponderException( 397 SAMLUtils.bundle.getString("errorCreateArtifact")); 398 } 399 String sourceID = (String) SAMLServiceManager.getAttribute( 400 SAMLConstants.SITE_ID); 401 AssertionArtifact art = new AssertionArtifact(sourceID, handle); 402 String artString = art.getAssertionArtifact(); 403 String aID = assertion.getAssertionID(); 404 Entry entry = (Entry) idEntryMap.get(aID); 405 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 406 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 407 FedMonSAML1Svc.CREAD); 408 } 409 if ((entry == null) && !validateNumberOfAssertions(idEntryMap)) { 410 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 411 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 412 FedMonSAML1Svc.CMISS); 413 } 414 entry = new Entry(assertion, destID, artString, null); 415 try { 416 synchronized (idEntryMap) { 417 idEntryMap.put(aID, entry); 418 } 419 if ((agent != null) && 420 agent.isRunning() && 421 (saml1Svc != null)) 422 { 423 saml1Svc.incSAML1Cache( 424 FedMonSAML1Svc.ASSERTIONS, 425 FedMonSAML1Svc.CWRITE); 426 } 427 goThroughRunnable.addElement(aID); 428 } catch (Exception e) { 429 SAMLUtils.debug.error("AssertionManager.createAssertion" 430 + "Artifact(Assertion,String): couldn't add to " 431 + "idEntryMap." + e); 432 throw new SAMLResponderException( 433 SAMLUtils.bundle.getString("errorCreateArtifact")); 434 } 435 if (LogUtils.isAccessLoggable(java.util.logging.Level.FINER)) { 436 String[] data = {SAMLUtils.bundle.getString("assertionCreated"), 437 assertion.toString(true, true)}; 438 LogUtils.access(java.util.logging.Level.FINER, 439 LogUtils.ASSERTION_CREATED, data); 440 } else { 441 String[] data = {SAMLUtils.bundle.getString("assertionCreated"), 442 assertion.getAssertionID()}; 443 LogUtils.access(java.util.logging.Level.INFO, 444 LogUtils.ASSERTION_CREATED, data); 445 } 446 } else { 447 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 448 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 449 FedMonSAML1Svc.CHIT); 450 } 451 String preArtString = entry.getArtifactString(); 452 if (preArtString != null) { 453 if ((agent != null) && 454 agent.isRunning() && 455 (saml1Svc != null)) 456 { 457 saml1Svc.incSAML1Cache( 458 FedMonSAML1Svc.ARTIFACTS, 459 FedMonSAML1Svc.CREAD); 460 } 461 462 if (artEntryMap.containsKey(preArtString)) { 463 if ((agent != null) && 464 agent.isRunning() && 465 (saml1Svc != null)) 466 { 467 saml1Svc.incSAML1Cache( 468 FedMonSAML1Svc.ARTIFACTS, 469 FedMonSAML1Svc.CHIT); 470 } 471 SAMLUtils.debug.error("AssertionManager.createAssertion" 472 + "Artifact(Asssertion, String): Artifact exists for " 473 + "the assertion."); 474 throw new SAMLResponderException( 475 SAMLUtils.bundle.getString("errorCreateArtifact")); 476 } else { 477 if ((agent != null) && 478 agent.isRunning() && 479 (saml1Svc != null)) 480 { 481 saml1Svc.incSAML1Cache( 482 FedMonSAML1Svc.ARTIFACTS, 483 FedMonSAML1Svc.CMISS); 484 } 485 } 486 } 487 entry.setDestID(destID); 488 entry.setArtifactString(artString); 489 } 490 // add to artEntry map 491 try { 492 Object oldEntry = null; 493 synchronized (artEntryMap) { 494 oldEntry = artEntryMap.put(artString, new 495 ArtEntry(aID, System.currentTimeMillis() + 496 artifactTimeout)); 497 } 498 if (oldEntry != null) { 499 artifactTimeoutRunnable.removeElement(artString); 500 } 501 artifactTimeoutRunnable.addElement(artString); 502 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 503 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ARTIFACTS, 504 FedMonSAML1Svc.CWRITE); 505 } 506 } catch (Exception e) { 507 SAMLUtils.debug.error("AssertionManager.createAssertionArt" 508 + "fact(Assertion,String): couldn't add artifact to the " 509 + "artEntryMap", e); 510 throw new SAMLResponderException( 511 SAMLUtils.bundle.getString("errorCreateArtifact")); 512 } 513 String[] data = {SAMLUtils.bundle.getString("assertionArtifactCreated"), 514 artString, aID}; 515 LogUtils.access(java.util.logging.Level.INFO, 516 LogUtils.ASSERTION_ARTIFACT_CREATED, data); 517 return art; 518 } 519 520 /** 521 * This method gets all valid Assertions managed by this 522 * <code>AssertionManager</code>. 523 * @param token User's session object which is allowed to get all 524 * Assertion. 525 * @return A Set of valid Assertion IDs. Each element in the Set is a 526 * String representing an Assertion ID. 527 * @throws SAMLException If this method can not gets all valid Assertions. 528 * @supported.api 529 */ 530 public Set getAssertions(Object token) 531 throws SAMLException 532 { 533 if (token == null) { 534 SAMLUtils.debug.error("AssertionManager.getAssertions(Object" 535 + "): input session is null."); 536 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 537 } 538 539 if (!isSuperUser(token)) { 540 SAMLUtils.debug.error("AssertionManager.getAssertions(Object" 541 + "): Session doesn't have the privilege."); 542 throw new SAMLException(SAMLUtils.bundle.getString("noPrivilege")); 543 } 544 545 return idEntryMap.keySet(); 546 } 547 548 private boolean isSuperUser(Object token) { 549 try { 550 if (sessionProvider == null) { 551 SAMLUtils.debug.error("SessionProvider is null."); 552 return false; 553 } 554 String userID = (String) sessionProvider.getProperty(token, 555 Constants.UNIVERSAL_IDENTIFIER)[0]; 556 if (superUser != null && superUser.length() > 0) { 557 return superUser.equalsIgnoreCase(userID); 558 } 559 } catch (Exception e) { 560 if (SAMLUtils.debug.messageEnabled()) { 561 SAMLUtils.debug.message( 562 "AssertionManager.isSuperUser:Exception: ", e); 563 } 564 } 565 return false; 566 } 567 568 /** 569 * This method gets the Assertion based on the Assertion ID. 570 * @param id The Assertion ID. 571 * @return An Assertion identified by the Assertion ID. 572 * @throws SAMLException If this method can not get the Assertion. 573 */ 574 public Assertion getAssertion(String id) 575 throws SAMLException 576 { 577 if ((id == null) || (id.length() == 0)) { 578 SAMLUtils.debug.error("AssertionManager.getAssetion(String): " 579 + "id is null."); 580 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 581 } 582 AssertionIDReference idRef = new AssertionIDReference(id); 583 return getAssertion(idRef, null, false); 584 } 585 586 /** 587 * This method gets all valid <code>AssertionArtifacts</code> 588 * managed by this <code>AssertionManager</code>. 589 * 590 * @param token User's session object which is allowed to get all 591 * <code>AssertionArtifacts</code>. 592 * @return A Set of valid <code>AssertionArtifacts</code>. Each element in 593 * the Set is an <code>AssertionArtifacts</code> object representing 594 * an artifact. 595 * @throws SAMLException If this method can not gets all valid 596 * <code>AssertionArtifacts</code>. 597 * @supported.api 598 */ 599 public Set getAssertionArtifacts(Object token) 600 throws SAMLException 601 { 602 if (token == null) { 603 SAMLUtils.debug.error("AssertionManager.getAssertionArtifacts(" + 604 "Object token): input token is null."); 605 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 606 } 607 608 if (!isSuperUser(token)) { 609 SAMLUtils.debug.error("AssertionManager.getAssertionArtifacts(" + 610 "Object token): Session doesn't have the privilege."); 611 throw new SAMLException(SAMLUtils.bundle.getString("noPrivilege")); 612 } 613 614 return artEntryMap.keySet(); 615 } 616 617 /** 618 * Returns Assertion that contains <code>AuthenticationStatement</code>. 619 * @param id The String that contains authentication information which 620 * is needed to create the assertion. It could be a string 621 * representation of an id, a cookie, etc. 622 * @param artifact the value to be set in the SubjectConfirmation of the 623 * <code>AuthenticationStatement</code>. If it's null, 624 * <code>SubjectConfirmation</code> is set to bearer. 625 * @param destID A String that is the site the assertion is created for. 626 * @param targetUrl A URL String representing the target site 627 * @param version The relying party preferred Assertion version number. 628 * @return Assertion The created Assertion. 629 * @throws SAMLException If the Assertion cannot be created. 630 */ 631 public Assertion createSSOAssertion(String id, AssertionArtifact artifact, 632 String destID, String targetUrl, String version) 633 throws SAMLException { 634 return createSSOAssertion(id, artifact, null, null, destID, 635 targetUrl, version); 636 } 637 638 /** 639 * Returns Assertion that contains <code>AuthenticationStatement</code>. 640 * @param id The String that contains authentication information which 641 * is needed to create the assertion. It could be a string 642 * representation of an id, a cookie, etc. 643 * @param artifact the value to be set in the SubjectConfirmation of the 644 * <code>AuthenticationStatement</code>. If it's null, 645 * <code>SubjectConfirmation</code> is set to bearer. 646 * @param request The HttpServletRerquest object of the request. 647 * @param response The HttpServletResponse object. 648 * @param destID A String that is the site the assertion is created for. 649 * @param targetUrl A URL String representing the target site 650 * @param version The relying party preferred Assertion version number. 651 * @return Assertion The created Assertion. 652 * @throws SAMLException If the Assertion cannot be created. 653 */ 654 public Assertion createSSOAssertion(String id, AssertionArtifact artifact, 655 HttpServletRequest request, HttpServletResponse response, 656 String destID, String targetUrl, String version) 657 throws SAMLException 658 { 659 List attributes = null; 660 Map partnerURLs = (Map) SAMLServiceManager.getAttribute( 661 SAMLConstants.PARTNER_URLS); 662 SAMLServiceManager.SOAPEntry partnerEntry = 663 (SAMLServiceManager.SOAPEntry)partnerURLs.get(destID); 664 665 if (partnerEntry != null) { 666 try { 667 if (sessionProvider == null) { 668 throw new SAMLException(SAMLUtils.bundle.getString( 669 "nullSessionProvider")); 670 } 671 Object userSession = sessionProvider.getSession(id); 672 ConsumerSiteAttributeMapper cMapper = 673 partnerEntry.getConsumerSiteAttributeMapper(); 674 if (cMapper != null) { 675 attributes = cMapper.getAttributes(userSession, 676 request, response, targetUrl); 677 } else { 678 PartnerSiteAttributeMapper pMapper = 679 partnerEntry.getPartnerSiteAttributeMapper(); 680 if (pMapper != null) { 681 attributes = pMapper.getAttributes( 682 userSession, targetUrl); 683 } else { 684 SiteAttributeMapper mapper = 685 partnerEntry.getSiteAttributeMapper(); 686 if (mapper != null) { 687 attributes = mapper.getAttributes(userSession); 688 } 689 } 690 } 691 } catch ( SessionException ssoe) { 692 SAMLUtils.debug.error("AssertionManager.createAssertion(id):" 693 + " exception retrieving info from the Session", ssoe); 694 return null; 695 } 696 } 697 698 String nameIDFormat = request.getParameter( 699 SAMLConstants.NAME_ID_FORMAT); 700 if (artifact == null) { 701 // SAML post profile 702 if (version.equals(SAMLConstants.ASSERTION_VERSION_1_1)) { 703 // set minor version to 1 704 return createAssertion(id, artifact, destID, attributes, 705 SAMLConstants.CONFIRMATION_METHOD_BEARER, 1, nameIDFormat); 706 } else { 707 // set minor version to 0 708 return createAssertion(id, artifact, destID, attributes, 709 SAMLConstants.CONFIRMATION_METHOD_BEARER, 0, nameIDFormat); 710 } 711 } else { 712 if(version == null || version.equals( 713 SAMLConstants.ASSERTION_VERSION_1_0)) { 714 return createAssertion(id, artifact, destID, attributes, 715 SAMLConstants.DEPRECATED_CONFIRMATION_METHOD_ARTIFACT, 0, 716 nameIDFormat); 717 } else if (version.equals(SAMLConstants.ASSERTION_VERSION_1_1)) { 718 return createAssertion(id, artifact, destID, attributes, 719 SAMLConstants.CONFIRMATION_METHOD_ARTIFACT, 1, 720 nameIDFormat); 721 } else { 722 SAMLUtils.debug.error("Input version " + version + 723 " is not supported."); 724 return null; 725 } 726 } 727 } 728 729 private Assertion createAssertion(String id, AssertionArtifact artifact, 730 String destID, List attributes, String confirmationMethod, 731 int minorVersion, String nameIDFormat) throws SAMLException 732 { 733 // check input 734 if ((id == null) || (id.length() == 0)) { 735 if (SAMLUtils.debug.messageEnabled()) { 736 SAMLUtils.debug.message("AssertionManager.createAssertion(id):" 737 + "null input."); 738 } 739 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 740 } 741 validateNumberOfAssertions(idEntryMap); 742 String authMethod = null; 743 Date authInstant = null; 744 Object token = null; 745 String clientIP = null; 746 try { 747 if (sessionProvider == null) { 748 throw new SAMLException(SAMLUtils.bundle.getString( 749 "nullSessionProvider")); 750 } 751 token = sessionProvider.getSession(id); 752 authMethod = (String) sessionProvider.getProperty( 753 token, SessionProvider.AUTH_METHOD)[0]; 754 String authSSOInstant = (String) 755 sessionProvider.getProperty(token,"authInstant")[0]; 756 if (authSSOInstant == null || authSSOInstant.equals("")) { 757 authInstant = new Date(); 758 } else { 759 authInstant = DateUtils.stringToDate(authSSOInstant); 760 } 761 762 try { 763 InetAddress clientIPAddress = 764 InetAddress.getByName(sessionProvider.getProperty( 765 token,"Host")[0]); 766 clientIP = clientIPAddress.getHostAddress(); 767 } catch (Exception e) { 768 // catching exception here since client ip is optional 769 if (SAMLUtils.debug.messageEnabled()) { 770 SAMLUtils.debug.message("AssertionManager." + 771 "createAssertion(id):" + 772 "exception when obtaining client ip: ", e); 773 } 774 } 775 } catch (Exception e) { 776 SAMLUtils.debug.error("AssertionManager." + 777 "createAssertion(id):" + 778 " exception retrieving info from the Session: ", e); 779 return null; 780 } 781 782 Map partnerURLs = 783 (Map) SAMLServiceManager.getAttribute(SAMLConstants.PARTNER_URLS); 784 SAMLServiceManager.SOAPEntry partnerEntry = 785 (SAMLServiceManager.SOAPEntry)partnerURLs.get(destID); 786 787 NameIdentifierMapper niMapper = null; 788 if (partnerEntry != null) { 789 niMapper = partnerEntry.getNameIdentifierMapper(); 790 } 791 if (niMapper == null) { 792 niMapper = new DefaultNameIdentifierMapper(); 793 } 794 795 String srcID = 796 (String)SAMLServiceManager.getAttribute(SAMLConstants.SITE_ID); 797 798 NameIdentifier ni = niMapper.getNameIdentifier(token, srcID, destID, nameIDFormat); 799 if (ni == null) { 800 SAMLUtils.debug.error("AssertionManager.createAssertion(id): " + 801 "name identifier is null."); 802 return null; 803 } 804 805 SubjectConfirmation subConfirmation = null; 806 String artString = null; 807 if ((confirmationMethod != null) && (confirmationMethod.length() > 0)) { 808 subConfirmation = new SubjectConfirmation(confirmationMethod); 809 } else { 810 if (artifact != null) { 811 if (minorVersion == 0) { 812 // set default for SAML Artifact profile 813 // here, we use SAML 1.0 confirmation method as default. 814 confirmationMethod = 815 SAMLConstants.DEPRECATED_CONFIRMATION_METHOD_ARTIFACT; 816 } else { 817 confirmationMethod = 818 SAMLConstants.CONFIRMATION_METHOD_ARTIFACT; 819 } 820 subConfirmation = new SubjectConfirmation(confirmationMethod); 821 } else { 822 // set to bearer for POST profile 823 subConfirmation = new SubjectConfirmation( 824 SAMLConstants.CONFIRMATION_METHOD_BEARER); 825 } 826 } 827 828 if (artifact != null) { 829 artString = artifact.getAssertionArtifact(); 830 } 831 Subject sub = new Subject(ni, subConfirmation); 832 SubjectLocality subjLocality = null; 833 if ((clientIP != null) && (clientIP.length() != 0)) { 834 subjLocality = new SubjectLocality(clientIP, null); 835 } 836 Set statements = new HashSet(); 837 statements.add(new AuthenticationStatement(authMethod, authInstant, 838 sub, subjLocality, null)); 839 840 if ((attributes != null) && (!attributes.isEmpty())) { 841 statements.add(new AttributeStatement(sub, attributes)); 842 } 843 Date issueInstant = new Date(); 844 Date notBefore = new Date(issueInstant.getTime() - notBeforeSkew); 845 // TODO: this period will be different for bearer 846 Date notAfter = new Date(issueInstant.getTime() + assertionTimeout); 847 Conditions cond = new Conditions(notBefore, notAfter); 848 String issuer = (String) SAMLServiceManager.getAttribute( 849 SAMLConstants.ISSUER_NAME); 850 Assertion assertion = new Assertion(null, issuer, issueInstant, cond, 851 statements); 852 assertion.setMinorVersion(minorVersion); 853 String aIDString = assertion.getAssertionID(); 854 855 // TODO:set AuthorityBinding if any 856 857 if (((Boolean) SAMLServiceManager.getAttribute( 858 SAMLConstants.SIGN_ASSERTION)).booleanValue()) 859 { 860 assertion.signXML(); 861 } 862 863 Entry entry = new Entry(assertion, destID, artString, token); 864 try { 865 Object oldEntry = null; 866 synchronized (idEntryMap) { 867 oldEntry = idEntryMap.put(aIDString, entry); 868 } 869 if (oldEntry != null) { 870 assertionTimeoutRunnable.removeElement(aIDString); 871 } 872 assertionTimeoutRunnable.addElement(aIDString); 873 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 874 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 875 FedMonSAML1Svc.CWRITE); 876 } 877 } catch (Exception e) { 878 if (SAMLUtils.debug.messageEnabled()) { 879 SAMLUtils.debug.message("AssertionManager: couldn't add " 880 + "to idEntryMap.", e); 881 } 882 throw new SAMLResponderException( 883 SAMLUtils.bundle.getString("errorCreateAssertion")); 884 } 885 886 if (LogUtils.isAccessLoggable(java.util.logging.Level.FINER)) { 887 String[] data = { SAMLUtils.bundle.getString("assertionCreated"), 888 assertion.toString(true, true)}; 889 LogUtils.access(java.util.logging.Level.FINER, 890 LogUtils.ASSERTION_CREATED, data); 891 } else { 892 String[] data = { SAMLUtils.bundle.getString("assertionCreated"), 893 aIDString}; 894 LogUtils.access(java.util.logging.Level.INFO, 895 LogUtils.ASSERTION_CREATED, data); 896 } 897 898 if (artString != null) { 899 // put artifact in artEntryMap 900 try { 901 Object oldEntry = null; 902 synchronized (artEntryMap) { 903 oldEntry = artEntryMap.put(artString, new 904 ArtEntry(aIDString, 905 (System.currentTimeMillis() + artifactTimeout))); 906 } 907 if (oldEntry != null) { 908 artifactTimeoutRunnable.removeElement(artString); 909 } 910 artifactTimeoutRunnable.addElement(artString); 911 if ((agent != null) && agent.isRunning() && (saml1Svc != null)){ 912 saml1Svc.incSAML1Cache( 913 FedMonSAML1Svc.ARTIFACTS, 914 FedMonSAML1Svc.CWRITE); 915 } 916 } catch (Exception e) { 917 if (SAMLUtils.debug.messageEnabled()) { 918 SAMLUtils.debug.message("AssertionManager: couldn't add " 919 + "artifact to the artEntryMap.", e); 920 } 921 throw new SAMLResponderException( 922 SAMLUtils.bundle.getString("errorCreateArtifact")); 923 } 924 String[] data = {SAMLUtils.bundle.getString( 925 "assertionArtifactCreated"), artString, aIDString}; 926 LogUtils.access(java.util.logging.Level.INFO, 927 LogUtils.ASSERTION_ARTIFACT_CREATED, data); 928 } 929 930 if (token != null) { 931 // create a listener and add the listener to the token 932 AssertionSSOTokenListener listener = new AssertionSSOTokenListener( 933 aIDString, artString); 934 try { 935 sessionProvider.addListener(token, listener); 936 } catch (SessionException e) { 937 SAMLUtils.debug.error("AssertionManager.createAssertion(id):" 938 + " Couldn't add listener to session:", e); 939 } catch (UnsupportedOperationException uoe) { 940 SAMLUtils.debug.warning("AssertionManager.createAssertion(id):" 941 + " Operation add listener to session not supported:", 942 uoe); 943 } 944 } 945 946 return assertion; 947 } 948 949 /** 950 * Deletes an assertion from the server. This method is used by the 951 * AssertionSSOTokenListener and cleanup method in the package. 952 * @param assertionID the id of the Assertion to be deleted. 953 * @param artifact the artifact associated with this assertionID. 954 * When it's null, no artifact is associated with this assertionID. 955 */ 956 void deleteAssertion(String assertionID, String artifact) { 957 ArtEntry artEntry = null; 958 if (artifact != null) { 959 // this is the case when Session expired, and the assertion 960 // was created for artifact 961 artEntry = (ArtEntry) artEntryMap.remove(artifact); 962 String[] data = {SAMLUtils.bundle.getString( 963 "assertionArtifactRemoved"), artifact}; 964 LogUtils.access(java.util.logging.Level.FINE, 965 LogUtils.ASSERTION_ARTIFACT_REMOVED, data); 966 } 967 968 if (assertionID != null) { 969 Entry entry = null; 970 entry = (Entry) idEntryMap.remove(assertionID); 971 if (entry != null) { 972 String[] data = {SAMLUtils.bundle.getString("assertionRemoved"), 973 assertionID}; 974 LogUtils.access(java.util.logging.Level.FINE, 975 LogUtils.ASSERTION_REMOVED, data); 976 if (artifact == null) { 977 // this is the case when assertion expired, check to see 978 // if the assertion is associated with an artifact 979 String artString = entry.getArtifactString(); 980 if (artString != null) { 981 synchronized (artEntryMap) { 982 artEntryMap.remove(artString); 983 } 984 String[] data2 = {SAMLUtils.bundle.getString( 985 "assertionArtifactRemoved"), artifact}; 986 LogUtils.access(java.util.logging.Level.FINE, 987 LogUtils.ASSERTION_ARTIFACT_REMOVED, data2); 988 } 989 } 990 } 991 } else { 992 if ((artEntry != null) && SAMLServiceManager.getRemoveAssertion()) { 993 synchronized (idEntryMap) { 994 idEntryMap.remove(artEntry.getAssertionID()); 995 } 996 } 997 } 998 } 999 1000 /** 1001 * Gets assertion associated with the AssertionArtifact. 1002 * @param artifact An AssertionArtifact. 1003 * @param destID A Set of String that represents the destination site id. 1004 * The destination site requesting the assertion using 1005 * the artifact. This String is compared with the destID that 1006 * the artifact is created for originally. 1007 * @param destCheckFlag true if desire to match the destionation id, 1008 * otherwise it is false. If it is false, destID can 1009 * be any string, including null. 1010 * @return The Assertion referenced to by artifact. 1011 * @throws SAMLException If an error occurred during the process, or no 1012 * assertion maps to the input artifact. 1013 */ 1014 private Assertion getAssertion(AssertionArtifact artifact, Set destID, 1015 boolean destCheckFlag) 1016 throws SAMLException { 1017 if (SAMLUtils.debug.messageEnabled()) { 1018 SAMLUtils.debug.message("getAssertion(arti): destID set= " + 1019 Base64.encode(SAMLUtils.stringToByteArray( 1020 (String)destID.iterator().next()))); 1021 } 1022 // check the destination id; also if this artifact exists 1023 String artString = artifact.getAssertionArtifact(); 1024 1025 // get server id. 1026 String remoteUrl = SAMLUtils.getServerURL( 1027 artifact.getAssertionHandle()); 1028 if (remoteUrl != null) { // not this server 1029 // call AssertionManagerClient.getAssertion 1030 if (SAMLUtils.debug.messageEnabled()) { 1031 SAMLUtils.debug.message("AssertionManager.getAssertion(art, " + 1032 "destid: calling another server in lb site:" + remoteUrl); 1033 } 1034 AssertionManagerClient amc = new AssertionManagerClient( 1035 SAMLUtils.getFullServiceURL(remoteUrl)); 1036 return amc.getAssertion(artifact, destID); 1037 } // else 1038 // get the assertion ID 1039 String aIDString = null; 1040 long timeout = 0; 1041 1042 ArtEntry artEntry = (ArtEntry) artEntryMap.get(artString); 1043 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 1044 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ARTIFACTS, 1045 FedMonSAML1Svc.CREAD); 1046 } 1047 if (artEntry == null) { 1048 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 1049 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ARTIFACTS, 1050 FedMonSAML1Svc.CMISS); 1051 } 1052 if (SAMLUtils.debug.messageEnabled()) { 1053 SAMLUtils.debug.message("AssertionManager.getAssertion(art, de" 1054 + "stid): no Assertion found corresponding to artifact."); 1055 } 1056 throw new SAMLException( 1057 SAMLUtils.bundle.getString("noMatchingAssertion")); 1058 } else { 1059 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 1060 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ARTIFACTS, 1061 FedMonSAML1Svc.CHIT); 1062 } 1063 } 1064 aIDString = (String) artEntry.getAssertionID(); 1065 if (aIDString == null) { 1066 if (SAMLUtils.debug.messageEnabled()) { 1067 SAMLUtils.debug.message("AssertionManager.getAssertion(art, de" 1068 + "stid): no AssertionID found corresponding to artifact."); 1069 } 1070 throw new SAMLException( 1071 SAMLUtils.bundle.getString("noMatchingAssertion")); 1072 } 1073 1074 timeout = artEntry.getExpireTime(); 1075 if (System.currentTimeMillis() > timeout) { 1076 if (SAMLUtils.debug.messageEnabled()) { 1077 SAMLUtils.debug.message("AssertionManager.getAssertion(art, " 1078 + "destid): artifact timed out."); 1079 } 1080 throw new SAMLException( 1081 SAMLUtils.bundle.getString("artifactTimedOut")); 1082 } 1083 1084 Entry entry = null; 1085 entry = (Entry) idEntryMap.get(aIDString); 1086 if (entry == null) { 1087 if (SAMLUtils.debug.messageEnabled()) { 1088 SAMLUtils.debug.message("AssertionManager.getAssertion(art, de" 1089 + "stid): no Entry found corresponding to artifact."); 1090 } 1091 throw new SAMLException( 1092 SAMLUtils.bundle.getString("noMatchingAssertion")); 1093 } 1094 1095 if (destCheckFlag) { 1096 // check the destination id 1097 String dest = entry.getDestID(); 1098 if (dest == null) { 1099 if (SAMLUtils.debug.messageEnabled()) { 1100 SAMLUtils.debug.message("AssertionManager.getAssertion(" + 1101 "art, destid): no destID found corresponding to artifact."); 1102 } 1103 throw new SAMLException( 1104 SAMLUtils.bundle.getString("noDestIDMatchingArtifact")); 1105 } 1106 if (destID == null || !destID.contains(dest)) { 1107 if (SAMLUtils.debug.messageEnabled()) { 1108 SAMLUtils.debug.message("AssertionManager.getAssertion(art"+ 1109 ", destid): destinationID doesn't match."); 1110 } 1111 throw new SAMLException( 1112 SAMLUtils.bundle.getString("destIDNotMatch")); 1113 } 1114 } 1115 Assertion assertion = entry.getAssertion(); 1116 if (assertion == null) { 1117 if (SAMLUtils.debug.messageEnabled()) { 1118 SAMLUtils.debug.message("AssertionManager.getAssertion(art, de" 1119 + "stid): no Assertion found corresponding to aID."); 1120 } 1121 throw new SAMLException( 1122 SAMLUtils.bundle.getString("noMatchingAssertion")); 1123 } 1124 1125 // remove the asssertion from artEntryMap 1126 synchronized (artEntryMap) { 1127 artEntryMap.remove(artString); 1128 } 1129 artifactTimeoutRunnable.removeElement(artString); 1130 String[] data = {SAMLUtils.bundle.getString( 1131 "assertionArtifactVerified"), artString}; 1132 LogUtils.access(java.util.logging.Level.INFO, 1133 LogUtils.ASSERTION_ARTIFACT_VERIFIED, data); 1134 1135 if (SAMLServiceManager.getRemoveAssertion()) { 1136 synchronized(idEntryMap) { 1137 idEntryMap.remove(aIDString); 1138 } 1139 assertionTimeoutRunnable.removeElement(aIDString); 1140 } 1141 1142 // check the time of the assertion 1143 if (!assertion.isTimeValid()) { 1144 if (SAMLUtils.debug.messageEnabled()) { 1145 SAMLUtils.debug.message("AssertionManager: assertion " 1146 + aIDString + " is expired."); 1147 } 1148 throw new SAMLException( 1149 SAMLUtils.bundle.getString("assertionTimeNotValid")); 1150 } 1151 return assertion; 1152 } 1153 1154 /** 1155 * Gets assertion associated with the AssertionArtifact. 1156 * @param artifact An AssertionArtifact. 1157 * @param destID The destination site requesting the assertion using 1158 * the artifact. This String is compared with the destID that 1159 * the artifact is created for originally. 1160 * @return The Assertion referenced to by artifact. 1161 * @throws SAMLException If an error occurred during the process, or no 1162 * assertion maps to the input artifact. 1163 */ 1164 public Assertion getAssertion(AssertionArtifact artifact, String destID) 1165 throws SAMLException { 1166 if ((artifact == null) || destID == null || destID.length() == 0) { 1167 if (SAMLUtils.debug.messageEnabled()) { 1168 SAMLUtils.debug.message("AssertionManager: input is null."); 1169 } 1170 throw new SAMLRequesterException( 1171 SAMLUtils.bundle.getString("nullInput")); 1172 } 1173 Set destSet = new HashSet(); 1174 destSet.add(destID); 1175 return getAssertion(artifact, destSet, true); 1176 } 1177 1178 /** 1179 * Gets assertion associated with the AssertionArtifact. 1180 * @param artifact An AssertionArtifact. 1181 * @param destID A Set of String that represents the destination site id. 1182 * The destination site requesting the assertion using 1183 * the artifact. Each string in this set compares with the destID 1184 * that the artifact is created for originally. If found match, 1185 * continue the operation. Otherwise, throws error. 1186 * @return The Assertion referenced to by artifact. 1187 * @throws SAMLException If an error occurred during the process, or no 1188 * assertion maps to the input artifact. 1189 */ 1190 public Assertion getAssertion(AssertionArtifact artifact, Set destID) 1191 throws SAMLException { 1192 if ((artifact == null) || destID == null || destID.isEmpty()) { 1193 if (SAMLUtils.debug.messageEnabled()) { 1194 SAMLUtils.debug.message("AssertionManager: input is null."); 1195 } 1196 throw new SAMLRequesterException( 1197 SAMLUtils.bundle.getString("nullInput")); 1198 } 1199 return getAssertion(artifact, destID, true); 1200 } 1201 1202 /** 1203 * Gets assertion associated with the AssertionArtifact. 1204 * @param artifact An AssertionArtifact. 1205 * @return The Assertion referenced to by artifact. 1206 * @throws SAMLException If an error occurred during the process, or no 1207 * assertion maps to the input artifact. 1208 */ 1209 protected Assertion getAssertion(AssertionArtifact artifact) 1210 throws SAMLException { 1211 if ((artifact == null)) { 1212 if (SAMLUtils.debug.messageEnabled()) { 1213 SAMLUtils.debug.message("AssertionManager: input is null."); 1214 } 1215 throw new SAMLRequesterException( 1216 SAMLUtils.bundle.getString("nullInput")); 1217 } 1218 return getAssertion(artifact, null, false); 1219 } 1220 1221 /** 1222 * Gets assertion created from the query. 1223 * @param query An Assertion Query. 1224 * @param destID to whom the assertion will be created for. 1225 * @return The Assertion that is created from the query. 1226 * @throws SAMLException If the Assertion cannot be created due to an 1227 * error in the query or in the receiver. 1228 */ 1229 public Assertion getAssertion(Query query, String destID) 1230 throws SAMLException { 1231 if (query == null) { 1232 if (SAMLUtils.debug.messageEnabled()) { 1233 SAMLUtils.debug.message("AssertionManager.getAssertion: input" 1234 + " query is null."); 1235 } 1236 throw new SAMLRequesterException( 1237 SAMLUtils.bundle.getString("nullInput")); 1238 } 1239 1240 Assertion result = null; 1241 int queryType = query.getQueryType(); 1242 if (queryType == Query.AUTHENTICATION_QUERY) { 1243 result = getAuthenticationAssertion((AuthenticationQuery)query, 1244 destID); 1245 } else if (queryType == Query.AUTHORIZATION_DECISION_QUERY) { 1246 result = getAuthorizationDecisionAssertion( 1247 (AuthorizationDecisionQuery)query, destID); 1248 } else if (queryType == Query.ATTRIBUTE_QUERY) { 1249 result = getAttributeAssertion((AttributeQuery)query, destID); 1250 } else { 1251 if (SAMLUtils.debug.messageEnabled()) { 1252 SAMLUtils.debug.message("AssertionManager.getAssertion: this " 1253 + "type of query is not supported:" + queryType); 1254 } 1255 throw new SAMLRequesterException( 1256 SAMLUtils.bundle.getString("queryNotSupported")); 1257 } 1258 return result; 1259 } 1260 1261 /** 1262 * Gets assertion created from an AttributeQuery. 1263 * @param query An AttributeQuery. 1264 * @param destID to whom the assertion will be created for. Currently, 1265 * it is the <code>sourceID</code> of the site that sends the query. 1266 * @return The Assertion that is created from the query. 1267 * @throws SAMLException If the Assertion cannot be created. 1268 */ 1269 private Assertion getAttributeAssertion(AttributeQuery query, String destID) 1270 throws SAMLException 1271 { 1272 if (query == null) { 1273 // no need to log the error again 1274 return null; 1275 } 1276 1277 if ((destID == null) || (destID.length() == 0)) { 1278 if (SAMLUtils.debug.messageEnabled()) { 1279 SAMLUtils.debug.message("AssertionManager.getAttributeAssertion" 1280 + ": missing destID."); 1281 } 1282 throw new SAMLException( 1283 SAMLUtils.bundle.getString("missingDestID")); 1284 } 1285 validateNumberOfAssertions(idEntryMap); 1286 Map entries = (Map) SAMLServiceManager.getAttribute( 1287 SAMLConstants.PARTNER_URLS); 1288 if (entries == null) { 1289 if (SAMLUtils.debug.messageEnabled()) { 1290 SAMLUtils.debug.message("AssertionManager.getAttributeAssertion" 1291 + ": empty partner URL list."); 1292 } 1293 throw new SAMLException( 1294 SAMLUtils.bundle.getString("emptyPartnerURLList")); 1295 } 1296 1297 SAMLServiceManager.SOAPEntry destSite = (SAMLServiceManager.SOAPEntry) 1298 entries.get(destID); 1299 AttributeMapper attrMapper = null; 1300 if ((destSite == null) || 1301 ((attrMapper = destSite.getAttributeMapper()) == null)) 1302 { 1303 if (SAMLUtils.debug.messageEnabled()) { 1304 SAMLUtils.debug.message("AssertionManager.getAttributeAssertion" 1305 + ": couldn't obtain AttributeMapper."); 1306 } 1307 throw new SAMLException( 1308 SAMLUtils.bundle.getString("errorObtainAttributeMapper")); 1309 } 1310 1311 Subject subject = query.getSubject(); 1312 String tokenID = attrMapper.getSSOTokenID(query); 1313 Object token = null; 1314 String issuerName = (String) SAMLServiceManager.getAttribute( 1315 SAMLConstants.ISSUER_NAME); 1316 if (tokenID != null) { 1317 try { 1318 if (sessionProvider == null) { 1319 throw new SAMLException(SAMLUtils.bundle.getString( 1320 "nullSessionProvider")); 1321 } 1322 token = sessionProvider.getSession(tokenID); 1323 } catch (Exception e) { 1324 if (SAMLUtils.debug.messageEnabled()) { 1325 SAMLUtils.debug.message("AssertionManager.getAttribute" 1326 + "Assertion: invalid SSO token:", e); 1327 } 1328 throw new SAMLException( 1329 SAMLUtils.bundle.getString("invalidSSOToken")); 1330 } 1331 } else { // token is null 1332 Assertion assertion = attrMapper.getSSOAssertion(query); 1333 if (assertion == null) { 1334 if (SAMLUtils.debug.messageEnabled()) { 1335 SAMLUtils.debug.message("AssertionManager.getAttribute" 1336 + "Assertion: couldn't find SSOAssertion in query."); 1337 } 1338 throw new SAMLException( 1339 SAMLUtils.bundle.getString("noSSOAssertion")); 1340 } 1341 if (!assertion.isSignatureValid()) { 1342 if (SAMLUtils.debug.messageEnabled()) { 1343 SAMLUtils.debug.message("AssertionManager.getAttribute" 1344 + "Assertion: SSOAssertion is signature invalid."); 1345 } 1346 throw new SAMLException( 1347 SAMLUtils.bundle.getString("assertionSignatureNotValid")); 1348 } 1349 if (!assertion.isTimeValid()) { 1350 if (SAMLUtils.debug.messageEnabled()) { 1351 SAMLUtils.debug.message("AssertionManager.getAttribute" 1352 + "Assertion: SSOAssertion is time invalid."); 1353 } 1354 throw new SAMLException( 1355 SAMLUtils.bundle.getString("assertionTimeNotValid")); 1356 } 1357 Iterator iter = assertion.getStatement().iterator(); 1358 Statement statement = null; 1359 Subject ssoSubject = null; 1360 while (iter.hasNext()) { 1361 statement = (Statement) iter.next(); 1362 if (statement.getStatementType() == 1363 Statement.AUTHENTICATION_STATEMENT) 1364 { 1365 ssoSubject = ((AuthenticationStatement) statement). 1366 getSubject(); 1367 break; 1368 } 1369 } 1370 if (ssoSubject == null) { 1371 if (SAMLUtils.debug.messageEnabled()) { 1372 SAMLUtils.debug.message("AssertionManager.getAttribute" 1373 + "Assertion: missing AuthenticationStatement in " 1374 + "SSOAssertion."); 1375 } 1376 throw new SAMLException( 1377 SAMLUtils.bundle.getString("noAuthNStatement")); 1378 } 1379 String issuer = assertion.getIssuer(); 1380 String aID = assertion.getAssertionID(); 1381 if ((issuerName != null) && (issuerName.equals(issuer)) && 1382 (SAMLUtils.getServerURL(aID) == null)) 1383 { 1384 // this server is the issuer 1385 if (SAMLUtils.debug.messageEnabled()) { 1386 SAMLUtils.debug.message("AssertionManager.getAttrAssertion:" 1387 + "this server is the issuer."); 1388 } 1389 Entry entry = (Entry) idEntryMap.get(aID); 1390 if ((agent != null) && agent.isRunning() && (saml1Svc != null)){ 1391 saml1Svc.incSAML1Cache( 1392 FedMonSAML1Svc.ASSERTIONS, 1393 FedMonSAML1Svc.CREAD); 1394 } 1395 if (entry != null) { 1396 token = entry.getSSOToken(); 1397 if (token != null) { 1398 verifySSOTokenAndNI(token, 1399 ssoSubject.getNameIdentifier()); 1400 } 1401 if ((agent != null) && 1402 agent.isRunning() && 1403 (saml1Svc != null)) 1404 { 1405 saml1Svc.incSAML1Cache( 1406 FedMonSAML1Svc.ASSERTIONS, 1407 FedMonSAML1Svc.CHIT); 1408 } 1409 } else { 1410 if ((agent != null) && 1411 agent.isRunning() && 1412 (saml1Svc != null)) 1413 { 1414 saml1Svc.incSAML1Cache( 1415 FedMonSAML1Svc.ASSERTIONS, 1416 FedMonSAML1Svc.CMISS); 1417 } 1418 } 1419 } else { // this machine is not the issuer 1420 if (SAMLUtils.debug.messageEnabled()) { 1421 SAMLUtils.debug.message("AssertionManager.getAttrAssertion:" 1422 + "this server is not the issuer."); 1423 } 1424 token = checkAssertionAndCreateSSOToken(assertion, null, 1425 ssoSubject); 1426 } 1427 } 1428 1429 // get here then got a valid token 1430 List attributes = attrMapper.getAttributes(query, destID, token); 1431 if ((attributes == null) || (attributes.size() == 0)) { 1432 return null; 1433 } 1434 1435 Set stmtSet = new HashSet(); 1436 stmtSet.add(new AttributeStatement(subject, attributes)); 1437 Date issueInstant = new Date(); 1438 Date notBefore = new Date(issueInstant.getTime() - notBeforeSkew); 1439 Date notAfter = new Date(issueInstant.getTime() + assertionTimeout); 1440 Conditions cond = new Conditions(notBefore, notAfter); 1441 Assertion newAssertion = new Assertion(null, issuerName, issueInstant, 1442 cond, stmtSet); 1443 if (((Boolean) SAMLServiceManager.getAttribute( 1444 SAMLConstants.SIGN_ASSERTION)).booleanValue()) 1445 { 1446 newAssertion.signXML(); 1447 } 1448 String aIDString = newAssertion.getAssertionID(); 1449 // don't save the token and don't add listener 1450 Entry newEntry = new Entry(newAssertion, destID, null, null); 1451 1452 // add newEntry to idEntryMap 1453 try { 1454 Object oldEntry = null; 1455 synchronized (idEntryMap) { 1456 oldEntry = idEntryMap.put(aIDString, newEntry); 1457 } 1458 if (oldEntry != null) { 1459 assertionTimeoutRunnable.removeElement(aIDString); 1460 } 1461 assertionTimeoutRunnable.addElement(aIDString); 1462 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 1463 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 1464 FedMonSAML1Svc.CWRITE); 1465 } 1466 } catch (Exception e) { 1467 if (SAMLUtils.debug.messageEnabled()) { 1468 SAMLUtils.debug.message("AssertionManager.getAttributeAssertion" 1469 + " couldn't add assertion to the idEntryMap.", e); 1470 } 1471 } 1472 1473 if (LogUtils.isAccessLoggable(java.util.logging.Level.FINER)) { 1474 String[] data = { SAMLUtils.bundle.getString("assertionCreated"), 1475 newAssertion.toString(true, true)}; 1476 LogUtils.access(java.util.logging.Level.FINER, 1477 LogUtils.ASSERTION_CREATED, data); 1478 } else { 1479 String[] data = { SAMLUtils.bundle.getString("assertionCreated"), 1480 aIDString}; 1481 LogUtils.access(java.util.logging.Level.INFO, 1482 LogUtils.ASSERTION_CREATED, data); 1483 } 1484 1485 return newAssertion; 1486 } 1487 1488 /** 1489 * Gets assertion created from an AuthenticationQuery. 1490 * @param query An AuthenticationQuery. 1491 * @param destID to whom the assertion will be created for. 1492 * @return The Assertion that is created from the query. 1493 * @throws SAMLException If the Assertion cannot be created. 1494 */ 1495 private Assertion getAuthenticationAssertion( 1496 AuthenticationQuery query, String destID) throws SAMLException 1497 { 1498 if (query == null) { 1499 // no need to log the error again 1500 return null; 1501 } 1502 validateNumberOfAssertions(idEntryMap); 1503 1504 // get the subject of the query 1505 Subject subject = query.getSubject(); 1506 1507 // get SubjectConfirmation 1508 SubjectConfirmation sc = subject.getSubjectConfirmation(); 1509 if (sc == null) { 1510 if (SAMLUtils.debug.messageEnabled()) { 1511 SAMLUtils.debug.message("AssertionManager.getAuthNAssertion:" 1512 + " missing SubjectConfirmation."); 1513 } 1514 // since we couldn't find the SSOToken in SubjectConfirmationData 1515 // we don't know if the subject is authenticated to OpenAM. 1516 throw new SAMLException( 1517 SAMLUtils.bundle.getString("missingSubjectConfirmation")); 1518 } 1519 // check ConfirmationMethod 1520 if (!SAMLUtils.isCorrectConfirmationMethod(sc)) { 1521 // don't need to log again 1522 throw new SAMLException( 1523 SAMLUtils.bundle.getString("wrongConfirmationMethodValue")); 1524 } 1525 1526 // get SubjectConfirmationData 1527 Element scData = sc.getSubjectConfirmationData(); 1528 if (scData == null) { 1529 if (SAMLUtils.debug.messageEnabled()) { 1530 SAMLUtils.debug.message("AssertionManager.getAuthNAssertion:" 1531 + " missing SubjectConfirmationData in the Subject."); 1532 } 1533 throw new SAMLException( 1534 SAMLUtils.bundle.getString("missingSubjectConfirmationData")); 1535 } 1536 1537 // SSOTokenID == scData 1538 String authMethod = null; 1539 Date authInstant = null; 1540 String nameQualifier = null; 1541 String name = null; 1542 Object token = null; 1543 String clientIP = null; 1544 try { 1545 if (sessionProvider == null) { 1546 throw new SAMLException(SAMLUtils.bundle.getString( 1547 "nullSessionProvider")); 1548 } 1549 token = sessionProvider.getSession( 1550 XMLUtils.getElementString(scData)); 1551 authMethod = SAMLServiceManager.getAuthMethodURI( 1552 sessionProvider.getProperty(token, "AuthType")[0]); 1553 // get authenticationInstant 1554 authInstant = DateUtils.stringToDate( 1555 sessionProvider.getProperty(token, "authInstant")[0]); 1556 // get the nameQualifier of the NameIdentifier 1557 nameQualifier = XMLUtils.escapeSpecialCharacters( 1558 sessionProvider.getProperty(token, "Organization")[0]); 1559 // get the name of the NameIdentifier 1560 name = XMLUtils.escapeSpecialCharacters( 1561 sessionProvider.getPrincipalName(token)); 1562 try { 1563 InetAddress clientIPAddress = 1564 InetAddress.getByName(sessionProvider.getProperty( 1565 token,"ipaddress")[0]); 1566 clientIP = clientIPAddress.getHostAddress(); 1567 } catch (Exception e) { 1568 // catching exception here since clientIP is optional 1569 if (SAMLUtils.debug.messageEnabled()) { 1570 SAMLUtils.debug.message("AssertionManager." + 1571 "getAuthNAssertion: exception when getting " + 1572 "client ip."); 1573 } 1574 } 1575 } catch (Exception e) { 1576 if (SAMLUtils.debug.messageEnabled()) { 1577 SAMLUtils.debug.message("AssertionManager.getAuthNAssertion:" 1578 + " exception retrieving info from the SSOToken:", e); 1579 } 1580 throw new SAMLException( 1581 SAMLUtils.bundle.getString("wrongSubjectConfirmationData")); 1582 } 1583 1584 // get and check NameIdentifier 1585 NameIdentifier ni = subject.getNameIdentifier(); 1586 if (ni != null) { 1587 String niName = ni.getName(); 1588 String niNameQualifier = ni.getNameQualifier(); 1589 if (((niName != null) && (!niName.equalsIgnoreCase(name))) || 1590 ((niNameQualifier != null) && 1591 (!niNameQualifier.equalsIgnoreCase(nameQualifier)))) 1592 { 1593 if (SAMLUtils.debug.messageEnabled()) { 1594 SAMLUtils.debug.message("AssertionManager.getAuthNAssertion" 1595 + ": NameIdentifier is different from info in " 1596 + "SubjectConfirmation"); 1597 } 1598 throw new SAMLException( 1599 SAMLUtils.bundle.getString("wrongNameIdentifier")); 1600 } 1601 } 1602 1603 // get and check AuthenticationMethod in the query 1604 String am = query.getAuthenticationMethod(); 1605 // check it against authMethod 1606 if ((am != null) && (am.length() != 0) && 1607 (!am.equalsIgnoreCase(authMethod))) 1608 { 1609 if (SAMLUtils.debug.messageEnabled()) { 1610 SAMLUtils.debug.message("AssertionManager.getAuthNAssertion:" 1611 + " couldn't form an assertion matching the " 1612 + "AuthenticationMethod in the query."); 1613 } 1614 throw new SAMLException(SAMLUtils.bundle.getString( 1615 "authenticationMethodInQueryNotMatch")); 1616 } 1617 SubjectLocality subjLocality = null; 1618 if ((clientIP != null) && (clientIP.length() != 0)) { 1619 subjLocality = new SubjectLocality(clientIP, null); 1620 } 1621 AuthenticationStatement statement = 1622 new AuthenticationStatement(authMethod, authInstant, subject, 1623 subjLocality, null); 1624 Date issueInstant = new Date(); 1625 // get this period from the config 1626 Date notAfter = new Date(issueInstant.getTime() + assertionTimeout); 1627 Date notBefore = new Date(issueInstant.getTime() - notBeforeSkew); 1628 Conditions cond = new Conditions(notBefore, notAfter); 1629 String issuer = (String) SAMLServiceManager.getAttribute( 1630 SAMLConstants.ISSUER_NAME); 1631 Set statements = new HashSet(); 1632 statements.add(statement); 1633 Assertion assertion = new Assertion(null, issuer, issueInstant, cond, 1634 statements); 1635 if (((Boolean) SAMLServiceManager.getAttribute( 1636 SAMLConstants.SIGN_ASSERTION)).booleanValue()) 1637 { 1638 assertion.signXML(); 1639 } 1640 String aIDString = assertion.getAssertionID(); 1641 1642 Entry entry = new Entry(assertion, destID, null, token); 1643 1644 // add entry to idEntryMap 1645 try { 1646 Object oldEntry = null; 1647 synchronized (idEntryMap) { 1648 oldEntry = idEntryMap.put(aIDString, entry); 1649 } 1650 if (oldEntry != null) { 1651 assertionTimeoutRunnable.removeElement(aIDString); 1652 } 1653 assertionTimeoutRunnable.addElement(aIDString); 1654 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 1655 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 1656 FedMonSAML1Svc.CWRITE); 1657 } 1658 } catch (Exception e) { 1659 if (SAMLUtils.debug.messageEnabled()) { 1660 SAMLUtils.debug.message("AssertionManager.getAuthNAssertion:" 1661 + " couldn't add assertion to the idEntryMap.", e); 1662 } 1663 throw new SAMLResponderException( 1664 SAMLUtils.bundle.getString("errorCreateAssertion")); 1665 } 1666 1667 if (LogUtils.isAccessLoggable(java.util.logging.Level.FINER)) { 1668 String[] data = { SAMLUtils.bundle.getString("assertionCreated"), 1669 assertion.toString(true, true)}; 1670 LogUtils.access(java.util.logging.Level.FINER, 1671 LogUtils.ASSERTION_CREATED, data); 1672 } else { 1673 String[] data = { SAMLUtils.bundle.getString("assertionCreated"), 1674 aIDString}; 1675 LogUtils.access(java.util.logging.Level.INFO, 1676 LogUtils.ASSERTION_CREATED, data); 1677 } 1678 1679 // create a listener and add the listener to the token 1680 AssertionSSOTokenListener listener = 1681 new AssertionSSOTokenListener(aIDString); 1682 try { 1683 sessionProvider.addListener(token, listener); 1684 } catch (SessionException e) { 1685 SAMLUtils.debug.error("AssertionManager.getAuthNAssertion:" 1686 + " Couldn't add listener to token:", e); 1687 // don't need to throw an exception 1688 } 1689 1690 return assertion; 1691 } 1692 1693 /** 1694 * Gets assertion created from an AuthorizationDecisionQuery. 1695 * @param query An AuthorizationDecisionQuery. 1696 * @param destID to whom the assertion will be created for. 1697 * @return The Assertion that is created from the query. 1698 * @throws SAMLException If the Assertion cannot be created. 1699 */ 1700 private Assertion getAuthorizationDecisionAssertion( 1701 AuthorizationDecisionQuery query, String destID) 1702 throws SAMLException 1703 { 1704 return getAuthorizationDecisionAssertion(query, destID, true); 1705 } 1706 1707 /** 1708 * Gets assertion created from an AuthorizationDecisionQuery. 1709 * @param query An AuthorizationDecisionQuery. 1710 * @param destID to whom the assertion will be created for. 1711 * @param store if true, the assertion is stored internally. 1712 * @return The Assertion that is created from the query. 1713 * @throws SAMLException If the Assertion cannot be created. 1714 */ 1715 private Assertion getAuthorizationDecisionAssertion( 1716 AuthorizationDecisionQuery query, String destID, boolean store) 1717 throws SAMLException 1718 { 1719 if (query == null) { 1720 // no need to log the error again 1721 return null; 1722 } 1723 1724 if ((destID == null) || (destID.length() == 0)) { 1725 if (SAMLUtils.debug.messageEnabled()) { 1726 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion: " 1727 + "missing destID."); 1728 } 1729 throw new SAMLException( 1730 SAMLUtils.bundle.getString("missingDestID")); 1731 } 1732 1733 Map entries = (Map) SAMLServiceManager.getAttribute( 1734 SAMLConstants.PARTNER_URLS); 1735 if (entries == null) { 1736 if (SAMLUtils.debug.messageEnabled()) { 1737 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion: " 1738 + "empty partnerURL list."); 1739 } 1740 throw new SAMLException( 1741 SAMLUtils.bundle.getString("emptyPartnerURLList")); 1742 } 1743 1744 SAMLServiceManager.SOAPEntry destSite = (SAMLServiceManager.SOAPEntry) 1745 entries.get(destID); 1746 ActionMapper actionMapper = null; 1747 if ((destSite == null) || 1748 ((actionMapper = destSite.getActionMapper()) == null)) 1749 { 1750 if (SAMLUtils.debug.messageEnabled()) { 1751 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion: " 1752 + "couldn't obtain ActionMapper."); 1753 } 1754 throw new SAMLException( 1755 SAMLUtils.bundle.getString("errorObtainActionMapper")); 1756 } 1757 1758 Subject querySubject = query.getSubject(); 1759 NameIdentifier queryNI = querySubject.getNameIdentifier(); 1760 Object token = null; 1761 boolean existingToken = true; 1762 1763 String tokenID = actionMapper.getSSOTokenID(query); 1764 if (tokenID != null) { 1765 // if there is a token, then the token must be valid 1766 try { 1767 if (sessionProvider == null) { 1768 throw new SAMLException(SAMLUtils.bundle.getString( 1769 "nullSessionProvider")); 1770 } 1771 token = sessionProvider.getSession(tokenID); 1772 } catch (Exception e) { 1773 if (SAMLUtils.debug.messageEnabled()) { 1774 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion" 1775 + ": invalid SSO token:", e); 1776 } 1777 throw new SAMLException( 1778 SAMLUtils.bundle.getString("invalidSSOToken")); 1779 } 1780 verifySSOTokenAndNI(token, queryNI); 1781 } else { 1782 Assertion assertion = actionMapper.getSSOAssertion(query, destID); 1783 if (assertion != null) { 1784 // if there is an assertion, then it must be valid 1785 Map tokenMap = verifyAssertionAndGetSSOToken(querySubject, 1786 assertion); 1787 token = (Object) tokenMap.get("true"); 1788 if (token == null){ 1789 existingToken = false; 1790 token = (Object) tokenMap.get("false"); 1791 } 1792 } 1793 } 1794 1795 if (token == null) { 1796 if (SAMLUtils.debug.messageEnabled()) { 1797 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion: " 1798 + "Couldn't obtain ssotoken."); 1799 } 1800 throw new SAMLException( 1801 SAMLUtils.bundle.getString("cannotVerifySubject")); 1802 } 1803 1804 Map map = actionMapper.getAuthorizationDecisions(query, token, destID); 1805 1806 // no need to invalidate the newly created ssotoken since the token 1807 // will be invalidated/destroyed when the short maxSessionTime and 1808 // maxIdleTime are reached. 1809 return getAuthorizationDecisionAssertion(query, destID, true, 1810 token, existingToken, map); 1811 } 1812 1813 private Map verifyAssertionAndGetSSOToken(Subject querySubject, 1814 Assertion assertion) 1815 throws SAMLException 1816 { 1817 if ((querySubject == null) || (assertion == null)) { 1818 if (SAMLUtils.debug.messageEnabled()) { 1819 SAMLUtils.debug.message("AssertionManager.verifyAssertionAnd" 1820 + "GetSSOToken: null input."); 1821 } 1822 throw new SAMLException( 1823 SAMLUtils.bundle.getString("cannotVerifySubject")); 1824 } 1825 1826 if (!assertion.isSignatureValid()) { 1827 if (SAMLUtils.debug.messageEnabled()) { 1828 SAMLUtils.debug.message("AssertionManager.verifyAssertionAnd" 1829 + "GetSSOToken: SSOAssertion is signature invalid."); 1830 } 1831 throw new SAMLException( 1832 SAMLUtils.bundle.getString("assertionSignatureNotValid")); 1833 } 1834 if (!assertion.isTimeValid()) { 1835 if (SAMLUtils.debug.messageEnabled()) { 1836 SAMLUtils.debug.message("AssertionManager.verifyAssertionAnd" 1837 + "GetSSOToken: SSOAssertion is time invalid."); 1838 } 1839 throw new SAMLException( 1840 SAMLUtils.bundle.getString("assertionTimeNotValid")); 1841 } 1842 1843 // TODO: check AudienceRestrictionConditions if any 1844 1845 Map tokenMap = new HashMap(); 1846 Object token = null; 1847 String issuerName = (String) SAMLServiceManager.getAttribute( 1848 SAMLConstants.ISSUER_NAME); 1849 String issuer = assertion.getIssuer(); 1850 String aID = assertion.getAssertionID(); 1851 if ((issuerName != null) && (issuerName.equals(issuer)) && 1852 (SAMLUtils.getServerURL(aID) == null)) 1853 { 1854 // this server is the issuer 1855 if (SAMLUtils.debug.messageEnabled()) { 1856 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion:" 1857 + "this server is the issuer."); 1858 } 1859 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 1860 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 1861 FedMonSAML1Svc.CREAD); 1862 } 1863 Entry entry = (Entry) idEntryMap.get(aID); 1864 if (entry != null) { 1865 if ((agent != null) && agent.isRunning() && (saml1Svc != null)){ 1866 saml1Svc.incSAML1Cache( 1867 FedMonSAML1Svc.ASSERTIONS, 1868 FedMonSAML1Svc.CHIT); 1869 } 1870 token = entry.getSSOToken(); 1871 if (token != null) { 1872 verifySSOTokenAndNI(token, 1873 querySubject.getNameIdentifier()); 1874 tokenMap.put("true", token); 1875 return tokenMap; 1876 } 1877 } else { 1878 if ((agent != null) && agent.isRunning() && (saml1Svc != null)){ 1879 saml1Svc.incSAML1Cache( 1880 FedMonSAML1Svc.ASSERTIONS, 1881 FedMonSAML1Svc.CMISS); 1882 } 1883 } 1884 1885 if (SAMLUtils.debug.messageEnabled()) { 1886 SAMLUtils.debug.message("AssertionManager.verifyAssertionAnd" 1887 + "GetSSOToken: either not an AuthN assertion or token " 1888 + "is not for this subject."); 1889 } 1890 throw new SAMLException(SAMLUtils.bundle. 1891 getString("cannotVerifySubject")); 1892 } else { 1893 if (SAMLUtils.debug.messageEnabled()) { 1894 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion:" 1895 + "this server is not the issuer."); 1896 } 1897 Iterator iter = assertion.getStatement().iterator(); 1898 Statement statement = null; 1899 AuthenticationStatement ssoStatement = null; 1900 while (iter.hasNext()) { 1901 statement = (Statement) iter.next(); 1902 if (statement.getStatementType() == 1903 Statement.AUTHENTICATION_STATEMENT) 1904 { 1905 ssoStatement = (AuthenticationStatement) statement; 1906 break; 1907 } 1908 } 1909 if (ssoStatement == null) { 1910 if (SAMLUtils.debug.messageEnabled()) { 1911 SAMLUtils.debug.message("AssertionManager.verifyAssertion" 1912 + "AndGetSSOToken: missing AuthenticationStatement in " 1913 + "SSOAssertion."); 1914 } 1915 throw new SAMLException( 1916 SAMLUtils.bundle.getString("noAuthNStatement")); 1917 } 1918 1919 token = checkAssertionAndCreateSSOToken(assertion, 1920 (AuthenticationStatement)statement, querySubject); 1921 tokenMap.put("false", token); 1922 } 1923 return tokenMap; 1924 } 1925 1926 private void verifySSOTokenAndNI(Object token, NameIdentifier ni) 1927 throws SAMLException 1928 { 1929 String name = null; 1930 String nameQualifier = null; 1931 try { 1932 if (sessionProvider == null) { 1933 throw new SAMLException(SAMLUtils.bundle.getString( 1934 "nullSessionProvider")); 1935 } 1936 name = XMLUtils.escapeSpecialCharacters( 1937 sessionProvider.getPrincipalName(token)); 1938 nameQualifier = XMLUtils.escapeSpecialCharacters( 1939 sessionProvider.getProperty(token, "Organization")[0]); 1940 } catch (Exception e) { 1941 if (SAMLUtils.debug.messageEnabled()) { 1942 SAMLUtils.debug.message("AssertionManager.verifySSOTokenAndNI: " 1943 + "Session is not valid.", e); 1944 } 1945 throw new SAMLException( 1946 SAMLUtils.bundle.getString("cannotVerifySubject")); 1947 } 1948 1949 if (ni == null) { 1950 return; 1951 } 1952 1953 String niName = ni.getName(); 1954 String niNameQualifier = ni.getNameQualifier(); 1955 if (((niName != null) && (!niName.equalsIgnoreCase(name))) || 1956 ((niNameQualifier != null) && (!niNameQualifier. 1957 equalsIgnoreCase(nameQualifier)))) 1958 { 1959 if (SAMLUtils.debug.messageEnabled()) { 1960 SAMLUtils.debug.message("AssertionManager.verifySSOToken" 1961 + "AndNI: NameIdentifier is different from info in " 1962 + "token."); 1963 } 1964 throw new SAMLException(SAMLUtils.bundle. 1965 getString("wrongNameIdentifier")); 1966 } 1967 } 1968 1969 private Object checkAssertionAndCreateSSOToken(Assertion assertion, 1970 AuthenticationStatement statement, Subject subject) 1971 throws SAMLException 1972 { 1973 // check if issuer is on our list. 1974 String issuer = assertion.getIssuer(); 1975 SAMLServiceManager.SOAPEntry sourceSite = 1976 SAMLUtils.getSourceSite(issuer); 1977 if (sourceSite == null) { 1978 if (SAMLUtils.debug.messageEnabled()) { 1979 SAMLUtils.debug.message("AssertionManager.checkAssertionAnd" 1980 + "CreateSSOToken: issuer is not on the partnerURL list."); 1981 } 1982 throw new SAMLException(SAMLUtils.bundle. 1983 getString("cannotVerifySubject")); 1984 } 1985 1986 // TODO: check AudienceRestrictionCondition if any 1987 1988 if (statement != null) { 1989 // check the subject 1990 if ((subject == null) || (!subject.equals(statement.getSubject()))) 1991 { 1992 if (SAMLUtils.debug.messageEnabled()) { 1993 SAMLUtils.debug.message("AssertionManager.verifyAndGetSSO" 1994 + "Token: wrong subject in evidence."); 1995 } 1996 throw new SAMLException(SAMLUtils.bundle. 1997 getString("cannotVerifySubject")); 1998 } 1999 } 2000 return createTempSSOToken(assertion, subject, sourceSite); 2001 } 2002 2003 private Object createTempSSOToken(Assertion assertion, Subject subject, 2004 SAMLServiceManager.SOAPEntry sourceSite) 2005 throws SAMLException 2006 { 2007 List assertions = new ArrayList(); 2008 assertions.add(assertion); 2009 String srcID = sourceSite.getSourceID(); 2010 String name = null; 2011 String org = null; 2012 2013 PartnerAccountMapper paMapper = sourceSite.getPartnerAccountMapper(); 2014 if (paMapper != null) { 2015 Map map = paMapper.getUser(assertions, srcID, null); 2016 name = (String) map.get(PartnerAccountMapper.NAME); 2017 org = (String) map.get(PartnerAccountMapper.ORG); 2018 } 2019 2020 if ((org == null) || (name == null)) { 2021 if (SAMLUtils.debug.messageEnabled()) { 2022 SAMLUtils.debug.message("AssertionManager." + 2023 "createTempSSOToken: couldn't map the subject " + 2024 "to a local user."); 2025 } 2026 throw new SAMLRequesterException( 2027 SAMLUtils.bundle.getString("cannotMapSubject")); 2028 } else { 2029 if (SAMLUtils.debug.messageEnabled()) { 2030 SAMLUtils.debug.message("AssertionManager." + 2031 "createTempSSOToken: org = " + org + ", name = " + 2032 name); 2033 } 2034 } 2035 2036 Object token = null; 2037 try { 2038 Map infoMap = new HashMap(); 2039 if ((org != null) && (org.length() != 0)) { 2040 infoMap.put(SessionProvider.REALM, org); 2041 } else { 2042 infoMap.put(SessionProvider.REALM, "/"); 2043 } 2044 infoMap.put(SessionProvider.PRINCIPAL_NAME, name); 2045 infoMap.put(SessionProvider.AUTH_LEVEL, "0"); 2046 token = SAMLUtils.generateSession(null, null, infoMap); 2047 } catch (Exception e) { 2048 if (SAMLUtils.debug.messageEnabled()) { 2049 SAMLUtils.debug.message("AssertionManger." + 2050 "createTempSSOToken: Couldn't retrieve " + 2051 "the ssotoken.", e); 2052 } 2053 throw new SAMLResponderException( 2054 SAMLUtils.bundle.getString("errorCreateAssertion")); 2055 } 2056 return token; 2057 } 2058 2059 /** 2060 * @param addListener A listener to the single sign on token is added only 2061 * when both store and addListener are true. 2062 */ 2063 private Assertion getAuthorizationDecisionAssertion( 2064 AuthorizationDecisionQuery query, String destID, 2065 boolean store, Object token, 2066 boolean addListener, Map actionMap) 2067 throws SAMLException 2068 { 2069 if (actionMap == null) { 2070 if (SAMLUtils.debug.messageEnabled()) { 2071 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion: " 2072 + "actionMap from ActionMapper is null."); 2073 } 2074 throw new SAMLException( 2075 SAMLUtils.bundle.getString("nullAuthZDecision")); 2076 } 2077 2078 validateNumberOfAssertions(idEntryMap); 2079 int decision; 2080 List newActions = null; 2081 if ((newActions = (List) actionMap.get(ActionMapper.PERMIT)) != null) { 2082 decision = AuthorizationDecisionStatement.DecisionType.PERMIT; 2083 } else if ((newActions = (List) actionMap.get(ActionMapper.DENY)) 2084 != null) 2085 { 2086 decision = AuthorizationDecisionStatement.DecisionType.DENY; 2087 } else { 2088 newActions = (List) actionMap.get(ActionMapper.INDETERMINATE); 2089 if (newActions == null) { 2090 // try not to be too restrictive 2091 newActions = query.getAction(); 2092 } 2093 decision = 2094 AuthorizationDecisionStatement.DecisionType.INDETERMINATE; 2095 } 2096 2097 //create statement 2098 AuthorizationDecisionStatement statement = 2099 new AuthorizationDecisionStatement( 2100 query.getSubject(), query.getResource(), decision, 2101 newActions, query.getEvidence()); 2102 2103 Date issueInstant = new Date(); 2104 Date notAfter = new Date(issueInstant.getTime() + assertionTimeout); 2105 Date notBefore = new Date(issueInstant.getTime() - notBeforeSkew); 2106 Conditions cond = new Conditions(notBefore, notAfter); 2107 String issuer = (String) SAMLServiceManager.getAttribute( 2108 SAMLConstants.ISSUER_NAME); 2109 Set statements = new HashSet(); 2110 statements.add(statement); 2111 Assertion assertion = new Assertion(null, issuer, issueInstant, cond, 2112 statements); 2113 if (((Boolean) SAMLServiceManager.getAttribute( 2114 SAMLConstants.SIGN_ASSERTION)).booleanValue()) 2115 { 2116 assertion.signXML(); 2117 } 2118 String aIDString = assertion.getAssertionID(); 2119 2120 if (store) { 2121 Entry entry = null; 2122 if (addListener) { 2123 // create a listener and add the listener to the token 2124 AssertionSSOTokenListener listener = 2125 new AssertionSSOTokenListener(aIDString); 2126 try { 2127 if (sessionProvider == null) { 2128 throw new SAMLException(SAMLUtils.bundle. 2129 getString("nullSessionProvider")); 2130 } 2131 sessionProvider.addListener(token, listener); 2132 } catch (SessionException e) { 2133 SAMLUtils.debug.error("AssertionManager.getAuthNAssertion:" 2134 + " Couldn't get listener to token:", e); 2135 // don't need to throw an exception 2136 } 2137 } 2138 entry = new Entry(assertion, destID, null, null); 2139 2140 // put assertion in idEntryMap 2141 try { 2142 Object oldEntry = null; 2143 synchronized (idEntryMap) { 2144 oldEntry = idEntryMap.put(aIDString, entry); 2145 } 2146 if (oldEntry != null) { 2147 assertionTimeoutRunnable.removeElement(aIDString); 2148 } 2149 assertionTimeoutRunnable.addElement(aIDString); 2150 if ((agent != null) && agent.isRunning() && (saml1Svc != null)){ 2151 saml1Svc.incSAML1Cache( 2152 FedMonSAML1Svc.ASSERTIONS, 2153 FedMonSAML1Svc.CWRITE); 2154 } 2155 } catch (Exception e) { 2156 if (SAMLUtils.debug.messageEnabled()) { 2157 SAMLUtils.debug.message("AssertionManager.getAuthZAssertion" 2158 + ": couldn't add assertion to the idAssertionMap.", e); 2159 } 2160 throw new SAMLResponderException( 2161 SAMLUtils.bundle.getString("errorCreateAssertion")); 2162 } 2163 2164 if (LogUtils.isAccessLoggable(java.util.logging.Level.FINER)) { 2165 String[] data = {SAMLUtils.bundle.getString("assertionCreated"), 2166 assertion.toString(true, true)}; 2167 LogUtils.access(java.util.logging.Level.FINER, 2168 LogUtils.ASSERTION_CREATED, data); 2169 } else { 2170 String[] data = {SAMLUtils.bundle.getString("assertionCreated"), 2171 aIDString}; 2172 LogUtils.access(java.util.logging.Level.INFO, 2173 LogUtils.ASSERTION_CREATED, data); 2174 } 2175 } 2176 2177 return assertion; 2178 } 2179 2180 /** 2181 * Gets the Assertion referenced by an <code>AssertionIDReference</code>. 2182 * @param idRef The <code>AssertionIDReference</code> which references to an 2183 * Assertion. 2184 * @return the Assertion referenced by the <code>AsertionIDReference</code>. 2185 * @throws SAMLException If an error occurred during the process; or 2186 * the assertion could not be found. 2187 */ 2188 public Assertion getAssertion(AssertionIDReference idRef) 2189 throws SAMLException 2190 { 2191 return getAssertion(idRef, null, false); 2192 } 2193 2194 /** 2195 * Gets the Assertion referenced by an <code>AssertionIDReference</code>. 2196 * This method is usually used after the call 2197 * <code>AssertionManager.getAssertions(SSOToken)</code>. 2198 * The assertion is retrieved from this <code>AssertionManager</code> only. 2199 * @param idRef The <code>AssertionIDReference</code> which references to an 2200 * Assertion. 2201 * @param token Use's session object that is allowed to obtain the 2202 * assertion. This token must have top level administrator role. 2203 * @return the Assertion referenced by the <code>AsertionIDReference</code>. 2204 * @throws SAMLException If an error occurred during the process; the token 2205 * does not have the privilege; or the assertion could not be 2206 * found. 2207 * @supported.api 2208 */ 2209 public Assertion getAssertion(AssertionIDReference idRef, Object token) 2210 throws SAMLException { 2211 if (token == null) { 2212 SAMLUtils.debug.error("AssertionManager.getAssertion(idRef, token" 2213 + "): input token is null."); 2214 throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 2215 } 2216 2217 if (!isSuperUser(token)) { 2218 SAMLUtils.debug.error("AssertionManager.getAssertion(idRef, token" 2219 + "): Session doesn't have the privilege."); 2220 throw new SAMLException(SAMLUtils.bundle.getString("noPrivilege")); 2221 } 2222 return getAssertion(idRef, null, true); 2223 } 2224 2225 /** 2226 * Gets the Assertion referenced by an <code>AssertionIDReference</code>. 2227 * @param idRef The <code>AssertionIDReference</code> which references to an 2228 * Assertion. 2229 * @param destID The destination site id requesting the assertion using 2230 * the assertion id reference. This String is compared with the 2231 * <code>destID</code> that the assertion is created for originally. 2232 * This field is not used (could be null) if the assertion was 2233 * created without a <code>destID</code> originally. This String can 2234 * be obtained from converting the 20 byte site id sequence to char 2235 * array, then a new String from the char array. 2236 * @return the Assertion referenced by the <code>AsertionIDReference</code>. 2237 * @throws SAMLException If an error occurred during the process; or 2238 * the assertion could not be found. 2239 * @supported.api 2240 */ 2241 public Assertion getAssertion(AssertionIDReference idRef, String destID) 2242 throws SAMLException { 2243 if (destID == null) { 2244 return getAssertion(idRef, null, false); 2245 } else { 2246 Set destSet = new HashSet(); 2247 destSet.add(destID); 2248 return getAssertion(idRef, destSet, false); 2249 } 2250 } 2251 2252 /** 2253 * Gets the Assertion referenced by an <code>AssertionIDReference</code>. 2254 * @param idRef The <code>AssertionIDReference</code> which references to an 2255 * Assertion. 2256 * @param destID A Set of destination site id. The destination site id 2257 * requesting the assertion using the assertion id reference. 2258 * This String is compared with the <code>destID</code> that the 2259 * assertion is created for originally. This field is not used 2260 * (could be null) if the assertion was created without a 2261 * <code>destID</code> originally. This String can be obtained from 2262 * converting the 20 byte site id sequence to char array, then a new 2263 * String from the char array. 2264 * @return the Assertion referenced by the <code>AsertionIDReference</code>. 2265 * @throws SAMLException If an error occurred during the process; or 2266 * the assertion could not be found. 2267 * @supported.api 2268 */ 2269 public Assertion getAssertion(AssertionIDReference idRef, Set destID) 2270 throws SAMLException { 2271 return getAssertion(idRef, destID, false); 2272 } 2273 2274 /** 2275 * Gets the Assertion referenced by an <code>AssertionIDReference</code>. 2276 * @param id The <code>AssertionIDReference</code> which references to an 2277 * Assertion. 2278 * @param destID A Set of String that represents the destination id. 2279 * The destination site id requesting the assertion using 2280 * the assertion id reference. This String is compared with the 2281 * <code>destID</code> that the assertion is created for originally. 2282 * This field is not used (could be null) if the assertion was 2283 * created without a <code>destID</code> originally. This String can 2284 * be obtained from converting the 20 byte site id sequence to char 2285 * array, then a new String from the char array. 2286 * @param useToken A boolean value. If set to true, destID is not 2287 * checked against with the string that the assertion is created 2288 * for originallyr, the assertion is retrieved from this server 2289 * only. 2290 * @return the Assertion referenced by the <code>AsertionIDReference</code>. 2291 * @throws SAMLException If an error occurred during the process; or 2292 * the assertion could not be found. 2293 */ 2294 private Assertion getAssertion(AssertionIDReference idRef, Set destID, 2295 boolean useToken) 2296 throws SAMLException { 2297 if (SAMLUtils.debug.messageEnabled()) { 2298 SAMLUtils.debug.message("getAssertion(idRef): destID set=" + 2299 destID); 2300 } 2301 if (idRef == null) { 2302 if (SAMLUtils.debug.messageEnabled()) { 2303 SAMLUtils.debug.message("AssertionManager.getAssertion(Asser" 2304 + "tionIDRef): null AssertionID."); 2305 } 2306 throw new SAMLRequesterException( 2307 SAMLUtils.bundle.getString("nullInput")); 2308 } 2309 String aIDString = idRef.getAssertionIDReference(); 2310 if (!useToken) { 2311 // get server id. 2312 String remoteUrl = SAMLUtils.getServerURL(aIDString); 2313 if (remoteUrl != null) { // not this server 2314 // call AssertionManagerClient.getAssertion 2315 if (SAMLUtils.debug.messageEnabled()) { 2316 SAMLUtils.debug.message("AssertionManager." + 2317 "getAssertion(idRef): calling another server" + 2318 " in lb site:" + remoteUrl); 2319 } 2320 AssertionManagerClient amc = new AssertionManagerClient( 2321 SAMLUtils.getFullServiceURL(remoteUrl)); 2322 return amc.getAssertion(idRef, destID); 2323 } //else 2324 } 2325 2326 Entry entry = (Entry) idEntryMap.get(aIDString); 2327 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 2328 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 2329 FedMonSAML1Svc.CREAD); 2330 } 2331 if (entry == null) { 2332 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 2333 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 2334 FedMonSAML1Svc.CMISS); 2335 } 2336 if (SAMLUtils.debug.messageEnabled()) { 2337 SAMLUtils.debug.message("AssertionManager.getAssertion(Asser" 2338 + "tionIDRef): no matching assertion found in idEntryMap."); 2339 } 2340 throw new SAMLException( 2341 SAMLUtils.bundle.getString("noMatchingAssertion")); 2342 } else { 2343 if ((agent != null) && agent.isRunning() && (saml1Svc != null)) { 2344 saml1Svc.incSAML1Cache(FedMonSAML1Svc.ASSERTIONS, 2345 FedMonSAML1Svc.CHIT); 2346 } 2347 } 2348 2349 Assertion assertion = entry.getAssertion(); 2350 if (assertion == null) { 2351 if (SAMLUtils.debug.messageEnabled()) { 2352 SAMLUtils.debug.message("AssertionManager.getAssertion(" 2353 + "AssertionIDRef): no matching assertion found."); 2354 } 2355 throw new SAMLException( 2356 SAMLUtils.bundle.getString("noMatchingAssertion")); 2357 } 2358 2359 if (!useToken) { 2360 // check if the destID is correct 2361 String dest = entry.getDestID(); 2362 if (dest != null) { 2363 if ((destID == null) || (!destID.contains(dest))) { 2364 if (SAMLUtils.debug.messageEnabled()) { 2365 SAMLUtils.debug.message("AssertionManager.getAssertion(" 2366 + "AssertionID): destID doesn't match."); 2367 } 2368 throw new SAMLException( 2369 SAMLUtils.bundle.getString("destIDNotMatch")); 2370 } 2371 } 2372 } 2373 2374 // check the time of the assertion 2375 if (!assertion.isTimeValid()) { 2376 if (SAMLUtils.debug.messageEnabled()) { 2377 SAMLUtils.debug.message("AssertionManager: assertion " 2378 + aIDString + " is expired."); 2379 } 2380 throw new SAMLException("assertionTimeNotValid"); 2381 } 2382 2383 return assertion; 2384 } 2385 2386 /** 2387 * Creates an AssertionArtifact. 2388 * @param id The String that contains authentication information which 2389 * is needed to create the assertion. It could be a string 2390 * representation of an id, a cookie, etc. 2391 * @param destID The destination site that the artifact is created for. 2392 * @return The AssertionArtifact. 2393 * @throws SAMLException If the AssertionArtifact cannot be created. 2394 */ 2395 public AssertionArtifact createAssertionArtifact(String id, 2396 String destID) throws SAMLException { 2397 return createAssertionArtifact(id, destID, null, null); 2398 } 2399 /** 2400 * Creates an AssertionArtifact. 2401 * @param id The String that contains authentication information which 2402 * is needed to create the assertion. It could be a string 2403 * representation of an id, a cookie, etc. 2404 * @param destID The destination site that the artifact is created for. 2405 * @param targetUrl A URL String representing the target site 2406 * @param version The relying party preferred Assertion version number. 2407 * @return The AssertionArtifact. 2408 * @throws SAMLException If the AssertionArtifact cannot be created. 2409 */ 2410 public AssertionArtifact createAssertionArtifact(String id, 2411 String destID, String targetUrl, 2412 String version) 2413 throws SAMLException { 2414 return createAssertionArtifact(id, destID, null, null, 2415 targetUrl, version); 2416 } 2417 /** 2418 * Creates an AssertionArtifact. 2419 * @param id The String that contains authentication information which 2420 * is needed to create the assertion. It could be a string 2421 * representation of an id, a cookie, etc. 2422 * @param destID The destination site that the artifact is created for. 2423 * @param request The HttpServletRerquest object of the request. 2424 * @param response The HttpServletResponse object. 2425 * @param targetUrl A URL String representing the target site 2426 * @param version The relying party preferred Assertion version number. 2427 * @return The AssertionArtifact. 2428 * @throws SAMLException If the AssertionArtifact cannot be created. 2429 */ 2430 public AssertionArtifact createAssertionArtifact(String id, 2431 String destID, HttpServletRequest request, 2432 HttpServletResponse response, String targetUrl, 2433 String version) throws SAMLException { 2434 // check input 2435 if ((id == null) || (destID == null)) { 2436 if (SAMLUtils.debug.messageEnabled()) { 2437 SAMLUtils.debug.message("AssertionManager: null input for" 2438 + " method createAssertionArtifact."); 2439 } 2440 throw new SAMLRequesterException( 2441 SAMLUtils.bundle.getString("nullInput")); 2442 } 2443 2444 Map partner = (Map) SAMLServiceManager.getAttribute( 2445 SAMLConstants.PARTNER_URLS); 2446 if ((partner == null) || (!partner.containsKey(destID))) { 2447 SAMLUtils.debug.error("AssertionManager.createAssertionArtifact:" + 2448 "(String, String): destID not in partner list."); 2449 throw new SAMLException( 2450 SAMLUtils.bundle.getString("destIDNotFound")); 2451 } 2452 2453 // create assertion id and artifact 2454 String handle = SAMLUtils.generateAssertionHandle(); 2455 if (handle == null) { 2456 if (SAMLUtils.debug.messageEnabled()) { 2457 SAMLUtils.debug.message("AssertionManager.createAssertionArt" 2458 + "ifact: couldn't generate assertion handle."); 2459 } 2460 throw new SAMLResponderException( 2461 SAMLUtils.bundle.getString("errorCreateArtifact")); 2462 } 2463 2464 String sourceID = (String) SAMLServiceManager.getAttribute( 2465 SAMLConstants.SITE_ID); 2466 AssertionArtifact art = new AssertionArtifact(sourceID, handle); 2467 Assertion assertion = createSSOAssertion(id, art, 2468 request, response, destID, targetUrl, version); 2469 try { 2470 if (version != null) { 2471 StringTokenizer st = new StringTokenizer(version,"."); 2472 if (st.countTokens() == 2) { 2473 assertion.setMajorVersion( 2474 Integer.parseInt(st.nextToken().trim())); 2475 assertion.setMinorVersion( 2476 Integer.parseInt(st.nextToken().trim())); 2477 } 2478 } 2479 } catch (NumberFormatException ne) { 2480 throw new SAMLException(ne.getMessage()); 2481 } 2482 return art; 2483 } 2484 2485 /** 2486 * This method returns the decision of an AuthorizationQuery. 2487 * @param authZQuery An AuthorizationQuery that contains the question: 2488 * Is this subject authorized to perfrom this action on 2489 * this resource? 2490 * @param destID the SourceID of the site where the query is from. 2491 * @return an int whose value is defined in 2492 * AuthorizationDecisionStatement.DecisionType. 2493 */ 2494 public int isAllowed(AuthorizationDecisionQuery authZQuery, String destID) { 2495 if (authZQuery == null) { 2496 SAMLUtils.debug.error("AssertionManager.isAllowed: null input."); 2497 return AuthorizationDecisionStatement.DecisionType.INDETERMINATE; 2498 } 2499 2500 Assertion assertion = null; 2501 try { 2502 assertion = getAuthorizationDecisionAssertion(authZQuery, destID, 2503 false); 2504 } catch (SAMLException e) { 2505 SAMLUtils.debug.error("AssertionManager.isAllowed: exception thrown" 2506 + " when trying to get an assertion from authZQuery. ", e); 2507 return AuthorizationDecisionStatement.DecisionType.INDETERMINATE; 2508 } 2509 2510 // double check, shouldn't be here 2511 if (assertion == null) { 2512 return AuthorizationDecisionStatement.DecisionType.INDETERMINATE; 2513 } 2514 2515 // Got an assertion 2516 Set statements = assertion.getStatement(); 2517 if ((statements != null) && (!statements.isEmpty())) { 2518 Iterator iter = statements.iterator(); 2519 while (iter.hasNext()) { 2520 Statement statement = (Statement) iter.next(); 2521 if (statement.getStatementType() == 2522 Statement.AUTHORIZATION_DECISION_STATEMENT) 2523 { 2524 // we know there should be only one authZstatement 2525 return ((AuthorizationDecisionStatement) statement). 2526 getDecision(); 2527 } 2528 } 2529 // still here means no authZstatement 2530 SAMLUtils.debug.error("AssertionManager.isAllowed: no " 2531 + "authZstatement in assertion."); 2532 return AuthorizationDecisionStatement.DecisionType.INDETERMINATE; 2533 } else { 2534 SAMLUtils.debug.error("AssertionManager.isAllowed: no statements in" 2535 + " assertion."); 2536 return AuthorizationDecisionStatement.DecisionType.INDETERMINATE; 2537 } 2538 } 2539 2540 boolean validateNumberOfAssertions(Map idEntryMap) 2541 throws SAMLResponderException 2542 { 2543 Integer maxNumber = (Integer) SAMLServiceManager.getAttribute( 2544 SAMLConstants.ASSERTION_MAX_NUMBER_NAME); 2545 int maxValue = maxNumber.intValue(); 2546 if ((maxValue != 0) && (idEntryMap.size() > maxValue)) { 2547 SAMLUtils.debug.error("AssertionManager.createAssertion" 2548 + "Artifact(assertion,String): reached maxNumber of " 2549 + "assertions."); 2550 throw new SAMLResponderException( 2551 SAMLUtils.bundle.getString("errorCreateArtifact")); 2552 } else { 2553 return false; 2554 } 2555 } 2556 2557 private class GoThroughRunnable extends GeneralTaskRunnable { 2558 private Set keys; 2559 private long runPeriod; 2560 2561 public GoThroughRunnable(long runPeriod) { 2562 this.keys = new HashSet(); 2563 this.runPeriod = runPeriod; 2564 } 2565 2566 public boolean addElement(Object obj) { 2567 synchronized (keys) { 2568 return keys.add(obj); 2569 } 2570 } 2571 2572 public boolean removeElement(Object obj) { 2573 synchronized (keys) { 2574 return keys.remove(obj); 2575 } 2576 } 2577 2578 public boolean isEmpty() { 2579 return false; 2580 } 2581 2582 public long getRunPeriod() { 2583 return runPeriod; 2584 } 2585 2586 public void run() { 2587 long currentTime = System.currentTimeMillis(); 2588 String keyString; 2589 Entry entry; 2590 Assertion assertion; 2591 SAMLUtils.debug.message("Clean up runnable wakes up.."); 2592 synchronized (keys) { 2593 Iterator keyIter = keys.iterator(); 2594 if (SAMLUtils.debug.messageEnabled()) { 2595 SAMLUtils.debug.message("AssertionManager::" 2596 +"CleanUpThread::number of assertions in " 2597 + "IdEntryMap:"+idEntryMap.size()); 2598 } 2599 while (keyIter.hasNext()) { 2600 keyString = (String) keyIter.next(); 2601 entry = (Entry) idEntryMap.get(keyString); 2602 if (entry != null) { 2603 assertion = entry.getAssertion(); 2604 if (assertion != null) { 2605 if (assertion.getConditions() != null) { 2606 if (!assertion.isTimeValid()) { 2607 keyIter.remove(); 2608 deleteAssertion(keyString, null); 2609 } 2610 } else { 2611 // if conditions are absent, calculate time 2612 // validity of assertion as if notBefore is 2613 // issueInstant - notBeforeSkew and notOnOrAfter 2614 // is assertion time out + issueInstant 2615 2616 Date issueInstant = assertion.getIssueInstant(); 2617 Date notBefore = new Date(issueInstant.getTime() 2618 - notBeforeSkew); 2619 Date notOnOrAfter = new Date( 2620 issueInstant.getTime() + assertionTimeout); 2621 if (!((currentTime >= notBefore.getTime()) && 2622 (currentTime < notOnOrAfter.getTime()))) { 2623 keyIter.remove(); 2624 deleteAssertion(keyString, null); 2625 } 2626 } 2627 } 2628 } 2629 } 2630 } 2631 } 2632 } 2633 2634}