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: PolicyEvaluator.java,v 1.7 2009/10/21 23:50:46 dillidorai Exp $ 026 * 027 */ 028 029/* 030 * Portions Copyrighted 2013 ForgeRock AS 031 */ 032package com.sun.identity.policy.client; 033 034import com.sun.identity.common.ShutdownListener; 035import com.sun.identity.common.ShutdownManager; 036import com.sun.identity.shared.debug.Debug; 037import com.iplanet.dpro.session.SessionException; 038import com.iplanet.sso.SSOException; 039import com.iplanet.sso.SSOToken; 040import com.iplanet.sso.SSOTokenManager; 041import com.sun.identity.policy.ActionDecision; 042import com.sun.identity.policy.PolicyDecision; 043import com.sun.identity.policy.ResBundleUtils; 044import com.sun.identity.policy.PolicyException; 045import com.sun.identity.policy.PolicyUtils; 046import com.sun.identity.policy.remote.PolicyEvaluationException; 047import com.sun.identity.security.AdminTokenAction; 048import com.sun.identity.security.AppSSOTokenProvider; 049import com.sun.identity.log.Logger; 050import com.sun.identity.log.LogRecord; 051import java.util.HashSet; 052import java.util.Iterator; 053import java.util.Map; 054import java.util.Set; 055import java.util.logging.Level; 056import java.security.AccessController; 057 058/** 059 * This class provides methods to get policy decisions 060 * for clients of policy service. 061 * This class uses XML/HTTP protocol to 062 * communicate with the Policy Service. 063 * Policy client API implementaion caches policy decision locally. 064 * The cache is updated through policy change notifications and/or 065 * polling. 066 * 067 * @supported.api 068 */ 069public class PolicyEvaluator { 070 071 static Debug debug = Debug.getInstance("amRemotePolicy"); 072 private PolicyProperties policyProperties; 073 private String serviceName; 074 private SSOTokenManager ssoTokenManager; 075 076 /** 077 * Reference to singleton ResourceResultCache instance 078 */ 079 private ResourceResultCache resourceResultCache; 080 081 AppSSOTokenProvider appSSOTokenProvider; 082 083 /** 084 * Logger object for access messages 085 */ 086 static Logger accessLogger; 087 088 /** 089 * Logger object for error messages 090 */ 091 static Logger errorLogger; 092 093 private static final String GET_RESPONSE_ATTRIBUTES 094 = "Get_Response_Attributes"; 095 096 private SSOToken appSSOToken; 097 098 /* 099 * Number of attempts to make to server if policy decision received 100 * from server has expired ttl 101 */ 102 private final static int RETRY_COUNT = 3; 103 104 private String logActions; 105 106 /** 107 * Creates an instance of client policy evaluator 108 * 109 * @param serviceName name of the service for which to create 110 * policy evaluator 111 * 112 * @throws PolicyException if required properties cannot be retrieved. 113 * @throws SSOException if application single sign on token is invalid. 114 * 115 * @supported.api 116 */ 117 public PolicyEvaluator(String serviceName) 118 throws PolicyException, SSOException { 119 if (debug.messageEnabled()) { 120 debug.message("PolicyEvaluator():Creating PolicyEvaluator:" 121 + "serviceName=" + serviceName ); 122 } 123 init(serviceName, null); //null appSSOTokenProvider 124 } 125 126 /** 127 * Creates an instance of client policy evaluator 128 * 129 * @param serviceName name of the service for which to create 130 * policy evalautor. 131 * @param appSSOTokenProvider an object where application single sign on 132 * token can be obtained. 133 * @throws PolicyException if required properties cannot be retrieved. 134 * @throws SSOException if application single sign on token is invalid. 135 */ 136 PolicyEvaluator(String serviceName, 137 AppSSOTokenProvider appSSOTokenProvider) 138 throws PolicyException, SSOException { 139 if (debug.messageEnabled()) { 140 debug.message("PolicyEvaluator():Creating PolicyEvaluator:" 141 + "serviceName="+ serviceName 142 + ":appSSOTokenProvider=" + appSSOTokenProvider); 143 } 144 if (serviceName == null) { 145 if (debug.warningEnabled()) { 146 debug.warning("PolicyEvaluator():" 147 + "serviceName is null"); 148 } 149 return; 150 } //else do the following 151 152 init(serviceName, appSSOTokenProvider); 153 } 154 155 /** 156 * Initializes an instance of client policy evaluator object 157 * 158 * @param serviceName name of the service for which to create 159 * policy evalautor 160 * @param appSSOTokenProvider an object where application single sign on 161 * token can be obtained. 162 * 163 * @throws PolicyException if required properties cannot be retrieved. 164 * @throws SSOException if application single sign on token is invalid. 165 * 166 */ 167 private void init(final String serviceName, 168 AppSSOTokenProvider appSSOTokenProvider) 169 throws PolicyException, SSOException { 170 this.ssoTokenManager = SSOTokenManager.getInstance(); 171 this.serviceName = serviceName; 172 this.appSSOTokenProvider = appSSOTokenProvider; 173 this.policyProperties = new PolicyProperties(); 174 this.logActions = policyProperties.getLogActions(); 175 this.resourceResultCache 176 = ResourceResultCache.getInstance(policyProperties); 177 appSSOToken = getNewAppSSOToken(); 178 179 if (PolicyProperties.previouslyNotificationEnabled()) { 180 if (policyProperties.useRESTProtocol()) { 181 resourceResultCache.removeRESTRemotePolicyListener(appSSOToken, 182 serviceName, PolicyProperties.getPreviousNotificationURL()); 183 } else { 184 resourceResultCache.removeRemotePolicyListener(appSSOToken, 185 serviceName, PolicyProperties.getPreviousNotificationURL()); 186 } 187 } 188 189 if (policyProperties.notificationEnabled()) { 190 191 // register remote policy listener policy service 192 if (debug.messageEnabled()) { 193 debug.message( "PolicyEvaluator.init():" 194 + "adding remote policy listener with policy " 195 + "service " + serviceName); 196 197 } 198 if (policyProperties.useRESTProtocol()) { 199 resourceResultCache.addRESTRemotePolicyListener(appSSOToken, 200 serviceName, policyProperties.getRESTNotificationURL()); 201 } else { 202 resourceResultCache.addRemotePolicyListener(appSSOToken, 203 serviceName, policyProperties.getNotificationURL()); 204 } 205 // Add a hook to remove our listener on shutdown. 206 ShutdownManager shutdownMan = ShutdownManager.getInstance(); 207 if (shutdownMan.acquireValidLock()) { 208 try { 209 shutdownMan.addShutdownListener(new ShutdownListener() { 210 @Override 211 public void shutdown() { 212 if (policyProperties.useRESTProtocol()) { 213 resourceResultCache.removeRESTRemotePolicyListener(appSSOToken, 214 serviceName, policyProperties.getRESTNotificationURL()); 215 if (debug.messageEnabled()) { 216 debug.message("PolicyEvaluator: called removeRESTRemotePolicyListener, service " 217 + serviceName + ", URL " + policyProperties.getRESTNotificationURL()); 218 } 219 } else { 220 resourceResultCache.removeRemotePolicyListener(appSSOToken, 221 serviceName, policyProperties.getNotificationURL()); 222 if (debug.messageEnabled()) { 223 debug.message("PolicyEvaluator: called removeRemotePolicyListener, service " 224 + serviceName + ", URL " + policyProperties.getNotificationURL()); 225 } 226 } 227 } 228 }); 229 } finally { 230 shutdownMan.releaseLockAndNotify(); 231 } 232 } 233 } 234 235 ActionDecision.setClientClockSkew(policyProperties.getClientClockSkew()); 236 237 if (debug.messageEnabled()) { 238 debug.message("PolicyEvaluator:" 239 + "initialized PolicyEvaluator"); 240 } 241 } 242 243 /** 244 * Evaluates a simple privilege of boolean type. The privilege indicates 245 * if the user can perform specified action on the specified resource. 246 * 247 * @param token single sign on token of the user evaluating policies 248 * @param resourceName name of the resource the user is trying to access 249 * @param actionName name of the action the user is trying to perform on 250 * the resource 251 * 252 * @return the result of the evaluation as a boolean value 253 * @throws PolicyException if result could not be computed for any 254 * reason other than single sign on token problem. 255 * @throws SSOException if single sign on token is not valid 256 * 257 */ 258 public boolean isAllowed(SSOToken token, String resourceName, 259 String actionName) throws PolicyException, 260 SSOException { 261 return isAllowed(token, resourceName, actionName, null); //null env Map 262 } 263 264 /** 265 * Evaluates simple privileges of boolean type. The privilege indicates 266 * if the user can perform specified action on the specified resource. 267 * The evaluation also depends on user's application environment parameters. 268 * 269 * @param token single sign on token of the user evaluating policies. 270 * @param resourceName name of the resource the user is trying to access 271 * @param actionName name of the action the user is trying to perform on 272 * the resource 273 * @param envParameters run time environment parameters 274 * 275 * @return the result of the evaluation as a boolean value 276 * 277 * @throws PolicyException if result could not be computed for 278 * reason other than single sign on token problem. 279 * @throws SSOException if single sign on token is not valid 280 * 281 * @supported.api 282 */ 283 public boolean isAllowed(SSOToken token, String resourceName, 284 String actionName, 285 Map envParameters) throws PolicyException, 286 SSOException { 287 if (debug.messageEnabled()) { 288 debug.message("PolicyEvaluator:isAllowed():" 289 + "token=" + token.getPrincipal().getName() 290 + ":resourceName="+ resourceName 291 + ":actionName=" + actionName 292 + ":envParameters) : entering"); 293 } 294 295 boolean actionAllowed = false; 296 Set actionNames = new HashSet(1); 297 actionNames.add(actionName); 298 PolicyDecision policyDecision = getPolicyDecision(token, resourceName, 299 actionNames, envParameters); 300 ActionDecision actionDecision = 301 (ActionDecision) policyDecision.getActionDecisions() 302 .get(actionName); 303 String trueValue = policyProperties.getTrueValue(serviceName, 304 actionName); 305 String falseValue = policyProperties.getFalseValue(serviceName, 306 actionName); 307 308 if ( (actionDecision != null) && (trueValue != null) 309 && (falseValue != null) ) { 310 Set set = (Set) actionDecision.getValues(); 311 if ( (set != null) ) { 312 if ( set.contains(falseValue) ) { 313 actionAllowed = false; 314 } else if ( set.contains(trueValue) ) { 315 actionAllowed = true; 316 } 317 } 318 } 319 320 String result = actionAllowed ? "ALLOW" : "DENY"; 321 String[] objs = {resourceName, actionName, result}; 322 if (PolicyProperties.ALLOW.equals(logActions) && actionAllowed) { 323 logAccessMessage(Level.INFO, 324 ResBundleUtils.getString( 325 "policy_eval_allow", objs),token); 326 } else if (PolicyProperties.DENY.equals(logActions) && !actionAllowed) { 327 logAccessMessage(Level.INFO, 328 ResBundleUtils.getString( 329 "policy_eval_deny", objs),token); 330 } else if (PolicyProperties.BOTH.equals(logActions) 331 || PolicyProperties.DECISION.equals(logActions)) { 332 logAccessMessage(Level.INFO, 333 ResBundleUtils.getString( 334 "policy_eval_result", objs),token); 335 } //else nothing to log 336 337 if (debug.messageEnabled()) { 338 debug.message("PolicyEvaluator.isAllowed():" 339 + "token=" + token.getPrincipal().getName() 340 + ":resourceName=" + resourceName 341 + ":actionName=" + actionName 342 + ":returning: " + actionAllowed); 343 } 344 return actionAllowed; 345 } 346 347 /** 348 * Evaluates privileges of the user to perform the specified actions 349 * on the specified resource. 350 * 351 * @param token single sign on token of the user evaluating policies. 352 * @param resourceName name of the resource the user is trying to access. 353 * @param actionNames Set of action names the user is trying to perform on 354 * the resource. 355 * 356 * @return policy decision 357 * @throws PolicyException if result could not be computed for any 358 * reason other than single sign on token problem. 359 * @throws SSOException if single sign on token is not valid 360 */ 361 public PolicyDecision getPolicyDecision(SSOToken token, 362 String resourceName, 363 Set actionNames) 364 throws PolicyException, SSOException { 365 return getPolicyDecision(token, resourceName, actionNames, null); 366 } 367 368 /** 369 * Evaluates privileges of the user to perform the specified actions 370 * on the specified resource. The evaluation also depends on user's 371 * run time environment parameters. 372 * 373 * @param token single sign on token of the user evaluating policies. 374 * @param resourceName name of the resource the user is trying to access 375 * @param actionNames Set of action names the user is trying to perform on 376 * the resource. 377 * @param envParameters run-time environment parameters 378 * @return policy decision 379 * @throws PolicyException if result could not be computed for any 380 * reason other than single sign on token problem. 381 * @throws SSOException if single sign on token is invalid or expired. 382 * 383 * @supported.api 384 */ 385 public PolicyDecision getPolicyDecision(SSOToken token, 386 String resourceName, 387 Set actionNames, 388 Map envParameters) 389 throws PolicyException, SSOException { 390 391 //validate the token 392 ssoTokenManager.validateToken(token); 393 394 if (debug.messageEnabled()) { 395 debug.message("PolicyEvaluator:getPolicyDecision():" 396 + "token=" + token.getPrincipal().getName() 397 + ":resourceName=" + resourceName 398 + ":actionName=" + actionNames + ":entering"); 399 } 400 401 PolicyDecision pd = null; 402 try { 403 pd = resourceResultCache.getPolicyDecision( 404 appSSOToken, serviceName, token, resourceName, 405 actionNames, envParameters, RETRY_COUNT); 406 } catch (InvalidAppSSOTokenException e) { 407 if (debug.warningEnabled()) { 408 debug.warning("PolicyEvaluator.getPolicyDecision():" 409 + "InvalidAppSSOTokenException occured:" 410 + "getting new appssotoken"); 411 } 412 appSSOToken = getNewAppSSOToken(); 413 if (policyProperties.notificationEnabled()) { 414 if (debug.warningEnabled()) { 415 debug.warning("PolicyEvaluator.getPolicyDecision():" 416 + "InvalidAppSSOTokenException occured:" 417 + "reRegistering remote policy listener"); 418 } 419 reRegisterRemotePolicyListener(appSSOToken); 420 } 421 pd = resourceResultCache.getPolicyDecision( 422 appSSOToken, serviceName, token, resourceName, 423 actionNames, envParameters, RETRY_COUNT); 424 425 } 426 427 if (debug.messageEnabled()) { 428 debug.message("PolicyEvaluator:getPolicyDecision():" 429 + "token=" + token.getPrincipal().getName() 430 + ":resourceName=" + resourceName 431 + ":actionNames=" + actionNames 432 + ":returning policyDecision:" + pd.toXML()); 433 } 434 435 Object[] objs = {resourceName, actionNames, pd.toXML()}; 436 if (PolicyProperties.DECISION.equals(logActions)) { 437 logAccessMessage(Level.INFO, 438 ResBundleUtils.getString( 439 "policy_eval_decision", objs),token); 440 } //else nothing to log 441 442 return pd; 443 } 444 445 /** 446 * Returns the application single sign on token, this token will be 447 * passed while initializing the <code>PolicyEvaluator</code> or 448 * if the application session token currently being used by 449 * this <code>PolicyEvaluator</code> has expired 450 * 451 * @return a valid application single sign on token. 452 */ 453 private SSOToken getNewAppSSOToken() throws PolicyException { 454 SSOToken token = null; 455 if (debug.messageEnabled()) { 456 debug.message("PolicyEvaluator.getNewAppSSOToken():" 457 + "entering"); 458 } 459 if (appSSOTokenProvider != null) { 460 token = appSSOTokenProvider.getAppSSOToken(); 461 try { 462 ssoTokenManager.refreshSession(token); 463 if (!ssoTokenManager.isValidToken(token)) { 464 if (debug.messageEnabled()) { 465 debug.message("PolicyEvaluator.getNewAppSSOToken():" 466 + "AdminTokenAction returned " 467 + " expired token, trying again"); 468 } 469 token = appSSOTokenProvider.getAppSSOToken(); 470 } 471 } catch (SSOException e) { 472 if (debug.warningEnabled()) { 473 debug.warning("PolicyEvaluator.getNewAppSSOToken():" 474 + "could not refresh session:", e); 475 } 476 token = appSSOTokenProvider.getAppSSOToken(); 477 } 478 } else { 479 token = (SSOToken) AccessController.doPrivileged( 480 AdminTokenAction.getInstance()); 481 try { 482 ssoTokenManager.refreshSession(token); 483 if (!ssoTokenManager.isValidToken(token)) { 484 if (debug.messageEnabled()) { 485 debug.message("PolicyEvaluator.getNewAppSSOToken():" 486 + "AdminTokenAction returned " 487 + " expired token, trying again"); 488 } 489 token = (SSOToken) AccessController.doPrivileged( 490 AdminTokenAction.getInstance()); 491 } 492 } catch (SSOException e) { 493 if (debug.warningEnabled()) { 494 debug.warning("PolicyEvaluator.getNewAppSSOToken():" 495 + "could not refresh session:", e); 496 } 497 token = (SSOToken) AccessController.doPrivileged( 498 AdminTokenAction.getInstance()); 499 } 500 } 501 if (token == null) { 502 debug.error("PolicyEvaluator.getNewAppSSOToken():, " 503 + "cannot obtain application SSO token"); 504 throw new PolicyException(ResBundleUtils.rbName, 505 "can_not_create_app_sso_token", null, null); 506 } 507 if (debug.messageEnabled()) { 508 debug.message("PolicyEvaluator.getNewAppSSOToken():" 509 + "returning token"); 510 } 511 return token; 512 } 513 514 /** 515 * Logs an access message from policy client api 516 * @param level logging level 517 * @param message message string 518 * @param token single sign on token of user 519 */ 520 private void logAccessMessage(Level level, String message, 521 SSOToken token) { 522 523 try { 524 if (accessLogger == null) { 525 accessLogger = (com.sun.identity.log.Logger) 526 Logger.getLogger("amRemotePolicy.access"); 527 if (accessLogger == null) { 528 if (debug.warningEnabled()) { 529 debug.warning("PolicyEvaluator.logAccessMessage:" 530 + "Failed to create Logger"); 531 } 532 return; 533 } 534 } 535 LogRecord lr = new LogRecord(level, message, token); 536 accessLogger.log(lr, appSSOToken); 537 } catch (Throwable ex) { 538 if (debug.warningEnabled()) { 539 debug.warning("PolicyEvaluator.logAccessMessage:Error" 540 + " writing access logs"); 541 } 542 } 543 544 } 545 546 /** 547 * Returns application single sign on token provider 548 * 549 * @return <code>AppSSOTokenProvider</code> Object. 550 */ 551 AppSSOTokenProvider getAppSSOTokenProvider() { 552 return appSSOTokenProvider; 553 } 554 555 /** 556 * Gets names of policy advices that could be handled by OpenSSO 557 * if PEP redirects user agent to OpenSSO. If the server reports 558 * an error indicating the app sso token provided was invalid, 559 * new app sso token is obtained from app 560 * sso token provider and another attempt is made to get policy advices 561 * 562 * @param refetchFromServer indicates whether to get the values fresh 563 * from OpenSSO or return the values from local cache 564 * @return names of policy advices that could be handled by OpenSSO 565 * Enterprise if PEP redirects user agent to OpenSSO. 566 * @throws InvalidAppSSOTokenException if the server reported that the 567 * app sso token provided was invalid 568 * @throws PolicyEvaluationException if the server reported any other error 569 * @throws PolicyException if there are problems in policy module 570 * while getting the result 571 * @throws SSOException if there are problems with sso token 572 * while getting the result 573 */ 574 public Set getAdvicesHandleableByAM(boolean refetchFromServer) 575 throws InvalidAppSSOTokenException, PolicyEvaluationException, 576 PolicyException, SSOException { 577 Set advicesHandleableByAM = null; 578 if (debug.messageEnabled()) { 579 debug.message("PolicyEvaluator.getAdvicesHandleableByAM(): Entering" 580 + "refetchFromServer=" + refetchFromServer); 581 } 582 try { 583 advicesHandleableByAM 584 = resourceResultCache.getAdvicesHandleableByAM( 585 appSSOToken, refetchFromServer); 586 } catch (InvalidAppSSOTokenException e) { 587 //retry with new app sso token 588 if (debug.warningEnabled()) { 589 debug.warning("PolicyEvaluator.getAdvicesHandleableByAM():" 590 + "got InvalidAppSSOTokenException, " 591 + " retrying with new app token"); 592 } 593 advicesHandleableByAM 594 = resourceResultCache.getAdvicesHandleableByAM( 595 getNewAppSSOToken(), refetchFromServer); 596 } catch (PolicyException pe) { 597 Throwable nestedException = pe.getNestedException(); 598 if ((nestedException != null) 599 && (nestedException instanceof SessionException)) { 600 //retry with new app sso token 601 if (debug.warningEnabled()) { 602 debug.warning("PolicyEvaluator.getAdvicesHandleableByAM():" 603 + "got SessionException, " 604 + " retrying with new app token"); 605 } 606 advicesHandleableByAM 607 = resourceResultCache.getAdvicesHandleableByAM( 608 getNewAppSSOToken(), refetchFromServer); 609 610 } else { 611 throw pe; 612 } 613 } 614 if (debug.messageEnabled()) { 615 debug.message("PolicyEvaluator.getAdvicesHandleableByAM():" 616 + " Returning advicesHandleableByAM=" 617 + advicesHandleableByAM); 618 } 619 return advicesHandleableByAM; 620 } 621 622 /** 623 * Returns XML string representation of advice map contained in the 624 * actionDecision. This is a convenience method for use by PEP. 625 * 626 * @param actionDecision actionDecision that contains the 627 * advices 628 * @return XML string representation of advice map contained in the 629 * actionDecision subject to the following rule. If the 630 * actionDecision is null, the return value would be null. 631 * Otherwise, if the actionDecision does not contain any advice, 632 * the return value would be null. Otherwise, actionDecision contains 633 * advices. In this case, if the advices contains at least one advice 634 * name that could be handled by AM, the complete advices element is 635 * serealized to XML and the XML string is returned. Otherwise, null 636 * is returned. 637 * @throws PolicyException for any abnormal condition encountered in 638 * policy module 639 * @throws SSOException for any abnormal condition encountered in 640 * session module 641 */ 642 public String getCompositeAdvice(ActionDecision actionDecision ) 643 throws PolicyException, SSOException { 644 645 if(debug.messageEnabled()) { 646 debug.message("PolicyEvaluator.getCompositeAdvice():" 647 + " entering, actionDecision = " + actionDecision.toXML()); 648 } 649 650 String compositeAdvice = null; 651 boolean matchFound = false; 652 Map advices = null; 653 if (actionDecision != null) { 654 advices = actionDecision.getAdvices(); 655 } 656 657 //false : use cached value 658 Set handleableAdvices = getAdvicesHandleableByAM(false); 659 660 if(debug.messageEnabled()) { 661 debug.message("PolicyEvaluator.getCompositeAdvice():" 662 + " handleableAdvices = " + handleableAdvices); 663 } 664 665 if ((advices != null) && !advices.isEmpty() 666 && (handleableAdvices !=null) 667 && (!handleableAdvices.isEmpty()) ) { 668 Set adviceKeys = advices.keySet(); 669 670 if(debug.messageEnabled()) { 671 debug.message("PolicyEvaluator.getCompositeAdvice():" 672 + " adviceKeys = " + adviceKeys); 673 } 674 675 Iterator keyIter = adviceKeys.iterator(); 676 while (keyIter.hasNext()) { 677 Object adviceKey = keyIter.next(); 678 if (handleableAdvices.contains(adviceKey)) { 679 matchFound = true; 680 if(debug.messageEnabled()) { 681 debug.message("PolicyEvaluator.getCompositeAdvice():" 682 + " matchFound = " + matchFound); 683 debug.message("PolicyEvaluator.getCompositeAdvice():" 684 + " common key = " + adviceKey); 685 } 686 break; 687 } 688 } 689 } 690 691 if (matchFound) { 692 compositeAdvice = PolicyUtils.advicesToXMLString(advices); 693 } 694 695 if(debug.messageEnabled()) { 696 debug.message("PolicyEvaluator.getCompositeAdvice():" 697 + " returning, compositeAdvcie = " + compositeAdvice); 698 } 699 700 return compositeAdvice; 701 } 702 703 /** 704 * Registers this client again with policy service to get policy 705 * change notifications 706 * 707 * @param appToken application sso token to use while registering with 708 * policy service to get notifcations 709 * 710 */ 711 void reRegisterRemotePolicyListener(SSOToken appToken) 712 throws PolicyException { 713 if (debug.messageEnabled()) { 714 debug.message("PolicyEvaluator.reRegisterRemotePolicyListener():" 715 + "entering"); 716 } 717 resourceResultCache.addRemotePolicyListener(appSSOToken, 718 serviceName, policyProperties.getNotificationURL(), 719 true); //reRegister 720 721 //clear policy decision cache 722 resourceResultCache.clearCachedDecisionsForService(serviceName); 723 724 if (debug.messageEnabled()) { 725 debug.message("PolicyEvaluator.reRegisterRemotePolicyListener():" 726 + "returning"); 727 } 728 } 729 730}