View Javadoc

1   /*
2    * Copyright 2007 University Corporation for Advanced Internet Development, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.common.binding.artifact;
18  
19  import java.io.StringReader;
20  import java.io.StringWriter;
21  
22  import org.opensaml.Configuration;
23  import org.opensaml.common.SAMLObject;
24  import org.opensaml.util.storage.StorageService;
25  import org.opensaml.xml.io.Marshaller;
26  import org.opensaml.xml.io.MarshallingException;
27  import org.opensaml.xml.io.Unmarshaller;
28  import org.opensaml.xml.io.UnmarshallingException;
29  import org.opensaml.xml.parse.ParserPool;
30  import org.opensaml.xml.parse.XMLParserException;
31  import org.opensaml.xml.util.DatatypeHelper;
32  import org.opensaml.xml.util.XMLHelper;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  import org.w3c.dom.Element;
36  
37  /**
38   * Basic artifact map implementation that uses a {@link StorageService} to store and retrieve artifacts.
39   */
40  public class BasicSAMLArtifactMap implements SAMLArtifactMap {
41  
42      /** Class Logger. */
43      private final Logger log = LoggerFactory.getLogger(BasicSAMLArtifactMap.class);
44  
45      /** Pool used to parse serialized messages. */
46      private ParserPool parserPool;
47  
48      /** Artifact mapping storage. */
49      private StorageService<String, SAMLArtifactMapEntry> artifactStore;
50  
51      /** Storage service partition used by this cache. default: artifact */
52      private String partition;
53  
54      /** Lifetime of an artifact in milliseconds. */
55      private long artifactLifetime;
56  
57      /**
58       * Constructor.
59       * 
60       * @param parser parser pool used to parse serialized messages
61       * @param storage artifact mapping storage
62       * @param lifetime lifetime of an artifact in milliseconds
63       */
64      public BasicSAMLArtifactMap(ParserPool parser, StorageService<String, SAMLArtifactMapEntry> storage, long lifetime) {
65          parserPool = parser;
66          artifactStore = storage;
67          partition = "artifact";
68          artifactLifetime = lifetime;
69      }
70  
71      /**
72       * Constructor.
73       * 
74       * @param storage artifact mapping storage
75       * @param storageParition name of storage service partition to use
76       * @param lifetime lifetime of an artifact in milliseconds
77       */
78      public BasicSAMLArtifactMap(StorageService<String, SAMLArtifactMapEntry> storage, String storageParition,
79              long lifetime) {
80          artifactStore = storage;
81          if (!DatatypeHelper.isEmpty(storageParition)) {
82              partition = DatatypeHelper.safeTrim(storageParition);
83          } else {
84              partition = "artifact";
85          }
86          artifactLifetime = lifetime;
87      }
88  
89      /** {@inheritDoc} */
90      public boolean contains(String artifact) {
91          return artifactStore.contains(partition, artifact);
92      }
93  
94      /** {@inheritDoc} */
95      public SAMLArtifactMapEntry get(String artifact) {
96          BasicSAMLArtifactMapEntry entry = (BasicSAMLArtifactMapEntry) artifactStore.get(partition, artifact);
97  
98          if(entry == null){
99              return null;
100         }
101         
102         if (entry.isExpired()) {
103             remove(artifact);
104             return null;
105         }
106 
107         try {
108             Element samlMessageElem = parserPool.parse(new StringReader(entry.getSeralizedMessage()))
109                     .getDocumentElement();
110             Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(samlMessageElem);
111             entry.setSAMLMessage((SAMLObject) unmarshaller.unmarshall(samlMessageElem));
112         } catch (XMLParserException e) {
113             log.error("Unable to parse serialized SAML message", e);
114         } catch (UnmarshallingException e) {
115             log.error("Unable to unmarshall serialized SAML message", e);
116         }
117 
118         return entry;
119     }
120 
121     /** {@inheritDoc} */
122     public void put(String artifact, String relyingPartyId, String issuerId, SAMLObject samlMessage)
123             throws MarshallingException {
124         StringWriter writer = new StringWriter();
125         Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(samlMessage);
126         XMLHelper.writeNode(marshaller.marshall(samlMessage), writer);
127 
128         BasicSAMLArtifactMapEntry artifactEntry = new BasicSAMLArtifactMapEntry(artifact, issuerId, relyingPartyId,
129                 writer.toString(), artifactLifetime);
130         artifactStore.put(partition, artifact, artifactEntry);
131     }
132 
133     /** {@inheritDoc} */
134     public void remove(String artifact) {
135         artifactStore.remove(partition, artifact);
136     }
137 }