| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| SamlTokenCxfOutInterceptor | 
 | 
 | 2.6;2.6 | ||||
| SamlTokenCxfOutInterceptor$SamlTokenCxfOutInterceptorInternal | 
 | 
 | 2.6;2.6 | 
| 1 |  /** | |
| 2 |   * Copyright 2010 The Kuali Foundation Licensed under the | |
| 3 |   * Educational Community License, Version 2.0 (the "License"); you may | |
| 4 |   * not use this file except in compliance with the License. You may | |
| 5 |   * obtain a copy of the License at | |
| 6 |   * | |
| 7 |   * http://www.osedu.org/licenses/ECL-2.0 | |
| 8 |   * | |
| 9 |   * Unless required by applicable law or agreed to in writing, | |
| 10 |   * software distributed under the License is distributed on an "AS IS" | |
| 11 |   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | |
| 12 |   * or implied. See the License for the specific language governing | |
| 13 |   * permissions and limitations under the License. | |
| 14 |   */ | |
| 15 | ||
| 16 |  package org.kuali.student.security.cxf.interceptors; | |
| 17 | ||
| 18 |  import java.util.Collections; | |
| 19 |  import java.util.Map; | |
| 20 |  import java.util.Set; | |
| 21 |  import java.util.Vector; | |
| 22 |  import java.util.logging.Level; | |
| 23 |  import java.util.logging.Logger; | |
| 24 | ||
| 25 |  import javax.xml.soap.SOAPElement; | |
| 26 |  import javax.xml.soap.SOAPEnvelope; | |
| 27 |  import javax.xml.soap.SOAPException; | |
| 28 |  import javax.xml.soap.SOAPFactory; | |
| 29 |  import javax.xml.soap.SOAPHeader; | |
| 30 |  import javax.xml.soap.SOAPMessage; | |
| 31 |  import javax.xml.soap.SOAPPart; | |
| 32 | ||
| 33 |  import org.apache.cxf.binding.soap.SoapFault; | |
| 34 |  import org.apache.cxf.binding.soap.SoapMessage; | |
| 35 |  import org.apache.cxf.binding.soap.SoapVersion; | |
| 36 |  import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; | |
| 37 |  import org.apache.cxf.common.i18n.Message; | |
| 38 |  import org.apache.cxf.common.logging.LogUtils; | |
| 39 |  import org.apache.cxf.interceptor.Fault; | |
| 40 |  import org.apache.cxf.phase.Phase; | |
| 41 |  import org.apache.cxf.phase.PhaseInterceptor; | |
| 42 |  import org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor; | |
| 43 |  import org.apache.ws.security.WSConstants; | |
| 44 |  import org.apache.ws.security.WSEncryptionPart; | |
| 45 |  import org.apache.ws.security.WSSConfig; | |
| 46 |  import org.apache.ws.security.WSSecurityException; | |
| 47 |  import org.apache.ws.security.handler.RequestData; | |
| 48 |  import org.apache.ws.security.handler.WSHandlerConstants; | |
| 49 |  import org.apache.ws.security.util.WSSecurityUtil; | |
| 50 |  import org.opensaml.SAMLAssertion; | |
| 51 |  import org.opensaml.SAMLException; | |
| 52 |  import org.w3c.dom.Document; | |
| 53 |  import org.w3c.dom.Element; | |
| 54 |  import org.w3c.dom.Node; | |
| 55 | ||
| 56 |  /*  Most of this code was taken from org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor | |
| 57 |      and modified for our purpose, additions should have comments starting with 'KS: ' | |
| 58 |       | |
| 59 |      This WSS4JOutInterceptor along with the wss4j library, handled the sender-vouches with a signed  | |
| 60 |      SAML Assertion correctly. The information to create that sender-vouches Assertion comes from the  | |
| 61 |      saml.properties file. | |
| 62 |      We needed to create another signed SAML Assertion that would hold the authenticated user and any  | |
| 63 |      SAML attributes along with the original voucher SAML Assertion. In the end the message would have two | |
| 64 |      signed SAML assertions. This was not possible with WSS4JOutInterceptor. see 'KS :' comments | |
| 65 |       | |
| 66 |  */ | |
| 67 | 0 |  public class SamlTokenCxfOutInterceptor extends AbstractWSS4JInterceptor { | 
| 68 | 0 |      private static final Logger LOG = LogUtils | 
| 69 |              .getL7dLogger(SamlTokenCxfOutInterceptor.class); | |
| 70 | ||
| 71 | 0 |      private static final Logger TIME_LOG = LogUtils | 
| 72 |              .getL7dLogger(SamlTokenCxfOutInterceptor.class, | |
| 73 |                            null, | |
| 74 | SamlTokenCxfOutInterceptor.class.getName() + "-Time"); | |
| 75 |      private SamlTokenCxfOutInterceptorInternal ending; | |
| 76 | 0 |      private SAAJOutInterceptor saajOut = new SAAJOutInterceptor(); | 
| 77 | private boolean mtomEnabled; | |
| 78 | ||
| 79 |      // KS : added to hold information used to create authenticated user, SAML Assertion | |
| 80 |      // KS : made this a ThreadLocal since we don't know if interceptors are thread-safe. | |
| 81 |      //private Map<String,String> samlProperties = new HashMap<String,String>(); | |
| 82 | 0 |      private ThreadLocal<Map<String,String>> samlPropertiesHolder = new ThreadLocal<Map<String,String>>(); | 
| 83 | 0 |      private ThreadLocal<SAMLAssertion> samlAssertionHolder = new ThreadLocal<SAMLAssertion>();; | 
| 84 | ||
| 85 |      public SamlTokenCxfOutInterceptor() { | |
| 86 | 0 |          super(); | 
| 87 | 0 |          setPhase(Phase.PRE_PROTOCOL); | 
| 88 | 0 |          getAfter().add(SAAJOutInterceptor.class.getName()); | 
| 89 | ||
| 90 | 0 |          ending = createEndingInterceptor(); | 
| 91 | 0 |      } | 
| 92 | ||
| 93 |      public SamlTokenCxfOutInterceptor(Map<String, Object> props) { | |
| 94 | 0 |          this(); | 
| 95 | 0 |          setProperties(props); | 
| 96 | 0 |      } | 
| 97 | ||
| 98 | public boolean isAllowMTOM() { | |
| 99 | 0 |          return mtomEnabled; | 
| 100 | } | |
| 101 |      /** | |
| 102 |       * Enable or disable mtom with WS-Security.   By default MTOM is disabled as | |
| 103 |       * attachments would not get encrypted or be part of the signature. | |
| 104 |       * @param mtomEnabled | |
| 105 |       */ | |
| 106 | public void setAllowMTOM(boolean allowMTOM) { | |
| 107 | 0 |          this.mtomEnabled = allowMTOM; | 
| 108 | 0 |      } | 
| 109 | ||
| 110 | public void handleMessage(SoapMessage mc) throws Fault { | |
| 111 |          //must turn off mtom when using WS-Sec so binary is inlined so it can | |
| 112 |          //be properly signed/encrypted/etc... | |
| 113 | 0 |          if (!mtomEnabled) { | 
| 114 | 0 |              mc.put(org.apache.cxf.message.Message.MTOM_ENABLED, false); | 
| 115 | } | |
| 116 | ||
| 117 | 0 |          if (mc.getContent(SOAPMessage.class) == null) { | 
| 118 | 0 |              saajOut.handleMessage(mc); | 
| 119 | } | |
| 120 | ||
| 121 | 0 |          mc.getInterceptorChain().add(ending); | 
| 122 | 0 |      }     | 
| 123 | public void handleFault(SoapMessage message) { | |
| 124 | 0 |          saajOut.handleFault(message); | 
| 125 | 0 |      }  | 
| 126 | ||
| 127 | public final SamlTokenCxfOutInterceptorInternal createEndingInterceptor() { | |
| 128 | 0 |          return new SamlTokenCxfOutInterceptorInternal(); | 
| 129 | } | |
| 130 | ||
| 131 | 0 |      final class SamlTokenCxfOutInterceptorInternal  | 
| 132 |          implements PhaseInterceptor<SoapMessage> { | |
| 133 | 0 |          public SamlTokenCxfOutInterceptorInternal() { | 
| 134 | 0 |              super(); | 
| 135 | 0 |          } | 
| 136 | ||
| 137 | public void handleMessage(SoapMessage mc) throws Fault { | |
| 138 |              // KS : added so we can create the authenticated user SAML Assertion before the message is handled. | |
| 139 | 0 |              String wsuId = handleMessageUserSAML(mc); | 
| 140 | ||
| 141 | 0 |              boolean doDebug = LOG.isLoggable(Level.FINE); | 
| 142 | 0 |              boolean doTimeDebug = TIME_LOG.isLoggable(Level.FINE); | 
| 143 | 0 |              SoapVersion version = mc.getVersion(); | 
| 144 | ||
| 145 | 0 |              long t0 = 0; | 
| 146 | 0 |              long t1 = 0; | 
| 147 | 0 |              long t2 = 0; | 
| 148 | ||
| 149 | 0 |              if (doTimeDebug) { | 
| 150 | 0 |                  t0 = System.currentTimeMillis(); | 
| 151 | } | |
| 152 | ||
| 153 | 0 |              if (doDebug) { | 
| 154 | 0 |                  LOG.fine("SamlTokenCxfOutInterceptor: enter handleMessage()"); | 
| 155 | } | |
| 156 | ||
| 157 |              // KS : this has been the problem and why we needed to code our own WSS4JOutInterceptor. | |
| 158 |              // WSS4JOutInterceptor needed to expose RequestData out of here so you can add the signature parts | |
| 159 |              // see code below, before doSenderAction();  Essentially anything signature parts, gets singed by wss4j. | |
| 160 | 0 |              RequestData reqData = new RequestData(); | 
| 161 | ||
| 162 | 0 |              reqData.setMsgContext(mc); | 
| 163 | ||
| 164 |              /* | |
| 165 |               * The overall try, just to have a finally at the end to perform some | |
| 166 |               * housekeeping. | |
| 167 |               */ | |
| 168 |              try { | |
| 169 |                  /* | |
| 170 |                   * Get the action first. | |
| 171 |                   */ | |
| 172 | 0 |                  Vector actions = new Vector(); | 
| 173 | 0 |                  String action = getString(WSHandlerConstants.ACTION, mc); | 
| 174 | 0 |                  if (action == null) { | 
| 175 | 0 |                      throw new SoapFault(new Message("NO_ACTION", LOG), version | 
| 176 | .getReceiver()); | |
| 177 | } | |
| 178 | ||
| 179 | 0 |                  int doAction = WSSecurityUtil.decodeAction(action, actions); | 
| 180 | 0 |                  if (doAction == WSConstants.NO_SECURITY) { | 
| 181 |                      return; | |
| 182 | } | |
| 183 | ||
| 184 |                  /* | |
| 185 |                   * For every action we need a username, so get this now. The | |
| 186 |                   * username defined in the deployment descriptor takes precedence. | |
| 187 |                   */ | |
| 188 | 0 |                  reqData.setUsername((String) getOption(WSHandlerConstants.USER)); | 
| 189 | 0 |                  if (reqData.getUsername() == null | 
| 190 |                          || reqData.getUsername().equals("")) { | |
| 191 | 0 |                      String username = (String) getProperty(reqData.getMsgContext(), | 
| 192 | WSHandlerConstants.USER); | |
| 193 | 0 |                      if (username != null) { | 
| 194 | 0 |                          reqData.setUsername(username); | 
| 195 | } | |
| 196 | } | |
| 197 | ||
| 198 |                  /* | |
| 199 |                   * Now we perform some set-up for UsernameToken and Signature | |
| 200 |                   * functions. No need to do it for encryption only. Check if | |
| 201 |                   * username is available and then get a passowrd. | |
| 202 |                   */ | |
| 203 | 0 |                  if ((doAction & (WSConstants.SIGN | WSConstants.UT | WSConstants.UT_SIGN)) != 0 | 
| 204 |                          && (reqData.getUsername() == null | |
| 205 |                          || reqData.getUsername().equals(""))) { | |
| 206 |                      /* | |
| 207 |                       * We need a username - if none throw an SoapFault. For | |
| 208 |                       * encryption there is a specific parameter to get a username. | |
| 209 |                       */ | |
| 210 | 0 |                      throw new SoapFault(new Message("NO_USERNAME", LOG), version | 
| 211 | .getReceiver()); | |
| 212 | } | |
| 213 | 0 |                  if (doDebug) { | 
| 214 | 0 |                      LOG.fine("Action: " + doAction); | 
| 215 | 0 |                      LOG.fine("Actor: " + reqData.getActor()); | 
| 216 | } | |
| 217 |                  /* | |
| 218 |                   * Now get the SOAP part from the request message and convert it | |
| 219 |                   * into a Document. This forces CXF to serialize the SOAP request | |
| 220 |                   * into FORM_STRING. This string is converted into a document. | |
| 221 |                   * During the FORM_STRING serialization CXF performs multi-ref of | |
| 222 |                   * complex data types (if requested), generates and inserts | |
| 223 |                   * references for attachements and so on. The resulting Document | |
| 224 |                   * MUST be the complete and final SOAP request as CXF would send it | |
| 225 |                   * over the wire. Therefore this must shall be the last (or only) | |
| 226 |                   * handler in a chain. Now we can perform our security operations on | |
| 227 |                   * this request. | |
| 228 |                   */ | |
| 229 | 0 |                  SOAPMessage saaj = mc.getContent(SOAPMessage.class); | 
| 230 | ||
| 231 | 0 |                  if (saaj == null) { | 
| 232 | 0 |                      LOG.warning("SAAJOutHandler must be enabled for WS-Security!"); | 
| 233 | 0 |                      throw new SoapFault(new Message("NO_SAAJ_DOC", LOG), version | 
| 234 | .getReceiver()); | |
| 235 | } | |
| 236 | ||
| 237 | 0 |                  Document doc = saaj.getSOAPPart(); | 
| 238 |                  /** | |
| 239 |                   * There is nothing to send...Usually happens when the provider | |
| 240 |                   * needs to send a HTTP 202 message (with no content) | |
| 241 |                   */ | |
| 242 | 0 |                  if (mc == null) { | 
| 243 |                      return; | |
| 244 | } | |
| 245 | ||
| 246 | 0 |                  if (doTimeDebug) { | 
| 247 | 0 |                      t1 = System.currentTimeMillis(); | 
| 248 | } | |
| 249 | ||
| 250 |                  // KS : any element represented by an encryptionPart and added to signatureParts will be signed. | |
| 251 |                  // The wsuId is the SAML Assertion we created above in handleMessageUserSAML(mc). | |
| 252 | 0 |                  WSEncryptionPart encP = new WSEncryptionPart(wsuId); | 
| 253 | 0 |                  reqData.getSignatureParts().add(encP); | 
| 254 |                  // KS : add the body, so it is also singed | |
| 255 | 0 |                  WSEncryptionPart encPBody = new WSEncryptionPart("Body",  | 
| 256 |                          doc.getDocumentElement().getNamespaceURI(), "Content"); | |
| 257 | 0 |                  reqData.getSignatureParts().add(encPBody); | 
| 258 | ||
| 259 | ||
| 260 | 0 |                  doSenderAction(doAction, doc, reqData, actions, Boolean.TRUE | 
| 261 | .equals(getProperty(mc, org.apache.cxf.message.Message.REQUESTOR_ROLE))); | |
| 262 | ||
| 263 | 0 |                  if (doTimeDebug) { | 
| 264 | 0 |                      t2 = System.currentTimeMillis(); | 
| 265 | 0 |                      TIME_LOG.fine("Send request: total= " + (t2 - t0) | 
| 266 |                              + " request preparation= " + (t1 - t0) | |
| 267 |                              + " request processing= " + (t2 - t1) | |
| 268 |                              + "\n"); | |
| 269 | } | |
| 270 | ||
| 271 | 0 |                  if (doDebug) { | 
| 272 | 0 |                      LOG.fine("SamlTokenCxfOutInterceptor: exit handleMessage()"); | 
| 273 | } | |
| 274 | 0 |              } catch (WSSecurityException e) { | 
| 275 | 0 |                  throw new SoapFault(new Message("SECURITY_FAILED", LOG), e, version | 
| 276 | .getSender()); | |
| 277 |              } finally { | |
| 278 | 0 |                  reqData.clear(); | 
| 279 | 0 |                  reqData = null; | 
| 280 | 0 |              } | 
| 281 | 0 |          } | 
| 282 | ||
| 283 |          public Set<String> getAfter() { | |
| 284 | 0 |              return Collections.emptySet(); | 
| 285 | } | |
| 286 | ||
| 287 |          public Set<String> getBefore() { | |
| 288 | 0 |              return Collections.emptySet(); | 
| 289 | } | |
| 290 | ||
| 291 |          public String getId() { | |
| 292 | 0 |              return SamlTokenCxfOutInterceptorInternal.class.getName(); | 
| 293 | } | |
| 294 | ||
| 295 |          public String getPhase() { | |
| 296 | 0 |              return Phase.POST_PROTOCOL; | 
| 297 | } | |
| 298 | ||
| 299 | public void handleFault(SoapMessage message) { | |
| 300 |              //nothing | |
| 301 | 0 |          } | 
| 302 | ||
| 303 |          // KS : All three methods below added to create the authenticated user SAML Assertion | |
| 304 | public String handleMessageUserSAML(SoapMessage msg) throws Fault { | |
| 305 | 0 |              String wsuId = null; | 
| 306 | 0 |              Node assertionNode = null; | 
| 307 | ||
| 308 |  /*            String user = getSamlProperties().get("user"); | |
| 309 |              String pgt = getSamlProperties().get("proxyGrantingTicket"); | |
| 310 |              String proxies = getSamlProperties().get("proxies"); | |
| 311 |              String issuer = getSamlProperties().get("samlIssuerForUser"); | |
| 312 |              String nameQualifier = getSamlProperties().get("samlIssuerForUser"); | |
| 313 |               | |
| 314 |              SAMLAssertion assertion = new SAMLAssertion(); | |
| 315 |              assertion.setIssuer(issuer); | |
| 316 |               | |
| 317 |              try{    | |
| 318 |                  // prepare subject | |
| 319 |                  SAMLNameIdentifier nameId = new SAMLNameIdentifier(user, nameQualifier, ""); | |
| 320 |                  String[] confirmationMethods = {SAMLSubject.CONF_SENDER_VOUCHES}; | |
| 321 |                  SAMLSubject subject = new SAMLSubject(); | |
| 322 |                  subject.setNameIdentifier(nameId); | |
| 323 |                  subject.setConfirmationMethods(Arrays.asList(confirmationMethods)); | |
| 324 |               | |
| 325 |                  // prepare auth statement | |
| 326 |                  SAMLAuthenticationStatement authStmt = new SAMLAuthenticationStatement(); | |
| 327 |                  authStmt.setAuthInstant(new Date()); | |
| 328 |                  authStmt.setAuthMethod(SAMLAuthenticationStatement.AuthenticationMethod_Password); | |
| 329 |                  authStmt.setSubject(subject); | |
| 330 |               | |
| 331 |                  // prepare attributes | |
| 332 |                  SAMLAttributeStatement attrStatement = new SAMLAttributeStatement(); | |
| 333 |                  SAMLAttribute attr1 = new SAMLAttribute(); | |
| 334 |                  attr1.setName("proxyGrantingTicket"); | |
| 335 |                  attr1.setNamespace("Namesapce_of_Attribute1"); | |
| 336 |               | |
| 337 |                  SAMLAttribute attr2 = new SAMLAttribute(); | |
| 338 |                  attr2.setName("proxies"); | |
| 339 |                  attr2.setNamespace("Namesapce_of_Attribute2"); | |
| 340 |               | |
| 341 |                   | |
| 342 |                  attr1.addValue(pgt); | |
| 343 |                  attr1.addValue("additional value for proxy granting ticket"); | |
| 344 |                  attr2.addValue(proxies); | |
| 345 |                  attr2.addValue("additional value for proxies"); | |
| 346 |                   | |
| 347 |                  attrStatement.addAttribute(attr1); | |
| 348 |                  attrStatement.addAttribute(attr2); | |
| 349 |                   | |
| 350 |                  SAMLSubject subjectInAttr = (SAMLSubject)subject.clone(); | |
| 351 |                  attrStatement.setSubject(subjectInAttr); | |
| 352 |                   | |
| 353 |                  // prepare Assertion | |
| 354 |                  assertion.addStatement(authStmt); | |
| 355 |                  assertion.addStatement(attrStatement); | |
| 356 |                   | |
| 357 |                  assertionNode = assertion.toDOM(); | |
| 358 |                   | |
| 359 |              } catch(SAMLException se){ | |
| 360 |                  Logger log = Logger.getLogger(SamlTokenCxfOutInterceptor.class.getName()); | |
| 361 |                  throw new Fault("Error when adding SAML Attributes or Attribute Statement : ", log, se); | |
| 362 |              } catch(CloneNotSupportedException cnse){ | |
| 363 |                  Logger log = Logger.getLogger(SamlTokenCxfOutInterceptor.class.getName()); | |
| 364 |                  throw new Fault("Error when cloning subject : ", log, cnse); | |
| 365 |              } */ | |
| 366 | ||
| 367 |              try{ | |
| 368 | 0 |                  assertionNode = getSamlAssertion().toDOM(); | 
| 369 | 0 |              } catch(SAMLException se){ | 
| 370 | 0 |                  Logger log = Logger.getLogger(SamlTokenCxfOutInterceptor.class.getName()); | 
| 371 | 0 |                  throw new Fault("Error when adding SAML Attributes or Attribute Statement : ", log, se); | 
| 372 | 0 |              } | 
| 373 | ||
| 374 |              try{ | |
| 375 |                  // get the envelope and create a header | |
| 376 | 0 |                  SOAPMessage soapMsg = msg.getContent(SOAPMessage.class); | 
| 377 | 0 |                  SOAPPart doc = soapMsg.getSOAPPart(); | 
| 378 | 0 |                  SOAPEnvelope envelope = doc.getEnvelope(); | 
| 379 | 0 |                  envelope.addHeader(); | 
| 380 | 0 |                  SOAPHeader soapHeader = soapMsg.getSOAPHeader(); | 
| 381 | ||
| 382 | ||
| 383 | 0 |                  SOAPFactory soapFactory = SOAPFactory.newInstance(); | 
| 384 | ||
| 385 |                  // create wsse:Security element | |
| 386 | 0 |                  SOAPElement wsseSecurity = soapFactory.createElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); | 
| 387 | ||
| 388 |                  // insert assertion in wsse:Security element | |
| 389 | 0 |                  if(assertionNode.getNodeType() == Node.ELEMENT_NODE ){ | 
| 390 | 0 |                      Element assertionElement = (Element)assertionNode; | 
| 391 | ||
| 392 |                      // add a wsu:Id | |
| 393 | 0 |                      wsuId = setWsuId(assertionElement); | 
| 394 | ||
| 395 | 0 |                      SOAPElement assertionSOAP = soapFactory.createElement(assertionElement); | 
| 396 | 0 |                      wsseSecurity.addChildElement(assertionSOAP); | 
| 397 | } | |
| 398 |                  // insert wsse:Security in header element | |
| 399 | 0 |                  soapHeader.addChildElement(wsseSecurity); | 
| 400 | 0 |              } catch(SOAPException se){ | 
| 401 | 0 |                  throw new Fault(se); | 
| 402 | 0 |              } | 
| 403 | 0 |              return wsuId; | 
| 404 | } | |
| 405 | ||
| 406 |          protected String setWsuId(Element bodyElement) { | |
| 407 | 0 |              String id = bodyElement.getAttributeNS(WSConstants.WSU_NS, "Id"); | 
| 408 | ||
| 409 | 0 |              if ((id == null) || (id.length() == 0)) { | 
| 410 | 0 |                  id = WSSConfig.getDefaultWSConfig().getIdAllocator().createId("id-", bodyElement); | 
| 411 | 0 |                  String prefix =  | 
| 412 | WSSecurityUtil.setNamespace(bodyElement, WSConstants.WSU_NS, WSConstants.WSU_PREFIX); | |
| 413 | 0 |                  bodyElement.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id); | 
| 414 | } | |
| 415 | 0 |              return id; | 
| 416 | } | |
| 417 | } | |
| 418 | ||
| 419 | public void setSamlProperties(Map<String, String> samlProperties){ | |
| 420 |          //this.samlProperties = samlProperties; | |
| 421 | 0 |          this.samlPropertiesHolder.set(samlProperties); | 
| 422 | 0 |      } | 
| 423 | ||
| 424 |      public Map<String, String> getSamlProperties() { | |
| 425 |          //return samlProperties; | |
| 426 | 0 |          return this.samlPropertiesHolder.get(); | 
| 427 | } | |
| 428 | ||
| 429 |      public SAMLAssertion getSamlAssertion() { | |
| 430 | 0 |          return this.samlAssertionHolder.get(); | 
| 431 | } | |
| 432 | ||
| 433 | public void setSamlAssertion(SAMLAssertion samlAssertion) { | |
| 434 | 0 |          this.samlAssertionHolder.set(samlAssertion); | 
| 435 | 0 |      } | 
| 436 | } |