Skip to Content.
Sympa Menu

mace-opensaml-users - Re: [OpenSAML] StorageService for SAMLArtifactMapEntry

Subject: OpenSAML user discussion

List archive

Re: [OpenSAML] StorageService for SAMLArtifactMapEntry


Chronological Thread 
  • From: Brent Putman <>
  • To:
  • Subject: Re: [OpenSAML] StorageService for SAMLArtifactMapEntry
  • Date: Mon, 29 Mar 2010 19:35:27 -0400



On 3/29/10 11:46 AM, Jim Cox wrote:
>
> The problem is that the BasicSAMLArtifactMapEntry stores the SAML
> Message as a String in the serializedMessage field. There is no getter
> for this field in the interface. I could cast it to a
> BasicSAMLArtifactMapEntry, but that getter is package private. Without a
> handle to this field, I don't see a way of re-constructing the entry.



Hmm, yeah, these impls classes seem a little screwy to me. The Basic-
map and entry impls are tighly coupled, essentially around the fact that
the map takes care of the serialization and deserialization of the
SAMLObject to the entry. This is made worse by the fact that the map
doesn't store the original SAMLObject on the entry on the put()
operation, just the serialized form. That fact coupled with the
package protected access you noted on the String getSeralizedMessage()
(sic) method mean that pretty much, the StorageService that is passed in
is assumed to be something that can store the entry as an object
directly (e.g. in-memory Map), or else take advantage of the fact that
it is Serializable (via AbstractExpiringObject) and store and recover it
via Java serialization, none of which is documented. To me, these
aren't the obvious "basic" impls, they're much more specialized that that.

I don't know if the failure to set the SAMLObject on the put() method,
and the package protected access specification, were accidental or
deliberate. If accidental, then we need to fix. If deliberate, then we
probably at least need to add alternative "basic" impls of these 2
interfaces that give the storage service access to all the data it needs
to store and reconstitute the entry object as it likes. I also think
the serialization stuff in the current impls might best be in the entry,
rather than in the map, since the entry is the thing that's
Serializable. IMHO the separation-of-concerns is off here.

For now, I think you have 2 options:

1) Use these classes as-is and in your StorageService impl, store and
retrieve from the database using Java serialization (maybe store in the
db as either a blob or the base64-encoded representation thereof).

2) Just write your own impls of the those 2 interfaces that don't assume
the above approach. There's essentially not much to them. More "basic"
examples that strip out all the serialization stuff are attached. That
then assumes that your DB storage service would store the entry data
using a relational approach over the various fields in the entry.

HTH,
Brent
/*
* Copyright 2007 University Corporation for Advanced Internet Development,
Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.opensaml.common.binding.artifact;

import org.opensaml.common.SAMLObject;
import org.opensaml.util.storage.StorageService;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.util.DatatypeHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Basic artifact map implementation that uses a
{@link
StorageService} to store and retrieve artifacts.
*/
public class BrentSAMLArtifactMap implements SAMLArtifactMap {

/** Class Logger. */
private final Logger log =
LoggerFactory.getLogger(BrentSAMLArtifactMap.class);

/** Artifact mapping storage. */
private StorageService<String, SAMLArtifactMapEntry> artifactStore;

/** Storage service partition used by this cache. default: artifact */
private String partition;

/** Lifetime of an artifact in milliseconds. */
private long artifactLifetime;

/**
* Constructor.
*
* @param storage artifact mapping storage
* @param lifetime lifetime of an artifact in milliseconds
*/
public BrentSAMLArtifactMap(StorageService<String, SAMLArtifactMapEntry>
storage, long lifetime) {
artifactStore = storage;
partition = "artifact";
artifactLifetime = lifetime;
}

/**
* Constructor.
*
* @param storage artifact mapping storage
* @param storageParition name of storage service partition to use
* @param lifetime lifetime of an artifact in milliseconds
*/
public BrentSAMLArtifactMap(StorageService<String, SAMLArtifactMapEntry>
storage, String storageParition,
long lifetime) {
artifactStore = storage;
if (!DatatypeHelper.isEmpty(storageParition)) {
partition = DatatypeHelper.safeTrim(storageParition);
} else {
partition = "artifact";
}
artifactLifetime = lifetime;
}

/**
{@inheritDoc}
*/
public boolean contains(String artifact) {
return artifactStore.contains(partition, artifact);
}

/**
{@inheritDoc}
*/
public SAMLArtifactMapEntry get(String artifact) {
SAMLArtifactMapEntry entry = artifactStore.get(partition, artifact);

if (entry == null) {
return null;
}

if (entry.isExpired()) {
log.debug("Entry was expired, removing from storage");
remove(artifact);
return null;
}

return entry;
}

/**
{@inheritDoc}
*/
public void put(String artifact, String relyingPartyId, String issuerId,
SAMLObject samlMessage)
throws MarshallingException {

SAMLArtifactMapEntry artifactEntry = new
BrentSAMLArtifactMapEntry(artifact, issuerId, relyingPartyId,
samlMessage, artifactLifetime);
artifactStore.put(partition, artifact, artifactEntry);
}

/**
{@inheritDoc}
*/
public void remove(String artifact) {
artifactStore.remove(partition, artifact);
}
}/*
* Copyright 2008 University Corporation for Advanced Internet Development,
Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.opensaml.common.binding.artifact;

import org.joda.time.DateTime;
import org.opensaml.common.SAMLObject;
import
org.opensaml.common.binding.artifact.SAMLArtifactMap.SAMLArtifactMapEntry;
import org.opensaml.util.storage.AbstractExpiringObject;

/** Basic implementation of
{@link
SAMLArtifactMapEntry}. */
public class BrentSAMLArtifactMapEntry extends AbstractExpiringObject
implements SAMLArtifactMapEntry {

/** Serial version UID. */
private static final long serialVersionUID = 4872905727625023964L;

/** SAML artifact being mapped. */
private String artifact;

/** Entity ID of the issuer of the artifact. */
private String issuer;

/** Entity ID of the receiver of the artifact. */
private String relyingParty;

/** SAML message mapped to the artifact. */
private SAMLObject message;

/**
* Constructor.
*
* @param artifact artifact associated with the message
* @param issuer issuer of the artifact
* @param relyingParty receiver of the artifact
* @param message the SAMLObject message mapped to the artifact
* @param lifetime lifetime of the artifact
*/
public BrentSAMLArtifactMapEntry(String artifact, String issuer, String
relyingParty,
SAMLObject message, long lifetime) {
super(new DateTime().plus(lifetime));
this.artifact = artifact;
this.issuer = issuer;
this.relyingParty = relyingParty;
this.message = message;
}

/**
{@inheritDoc}
*/
public String getArtifact() {
return artifact;
}

/**
{@inheritDoc}
*/
public String getIssuerId() {
return issuer;
}

/**
{@inheritDoc}
*/
public String getRelyingPartyId() {
return relyingParty;
}

/**
{@inheritDoc}
*/
public SAMLObject getSamlMessage() {
return message;
}

}


Archive powered by MHonArc 2.6.16.

Top of Page