package org.linkality.xacmlanalysr; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import com.sun.xacml.EvaluationCtx; import com.sun.xacml.attr.AttributeDesignator; import com.sun.xacml.attr.BagAttribute; import com.sun.xacml.attr.RFC822NameAttribute; import com.sun.xacml.attr.StringAttribute; import com.sun.xacml.cond.EvaluationResult; import com.sun.xacml.ctx.Status; import com.sun.xacml.finder.AttributeFinderModule; /** * This is an example <code>AttributeFinderModule</code> that looks up * attributes based on the context. This kind of functionality is useful if you * want to include some information in the Request and then use that information * as needed, during policy evaluation, to retrieve other attribute values. In * this case, the user's identity is included in the original Request, but the * policy needs to know about the user's group memberships. This module looks up * the groups based on the user's identity. * <p> * Because group membership is system-specific the actual retrieval of these * values is left out of this module. If you supply this code, however, you can * then retrive the values by saying * * <pre> * <SubjectAttributeDesignator AttributeId="subject-groups" * DataType="http://www.w3.org/2001/XMLSchema#string"/> * </pre> * * in your policies. * * @since 1.1 * @author seth proctor */ public class SampleAttrFinderModule extends AttributeFinderModule { // the one and only attribute identifier that this module supports private static final String SUPPORTED_ATTRIBUTE_ID = "group"; // the identifier and type of the user private static final String USER_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id"; private static final String USER_ID_TYPE = RFC822NameAttribute.identifier; // URI versions of the subject data private URI userId; private URI userIdType; /** * Default constructor. */ public SampleAttrFinderModule() throws URISyntaxException { // setup the subject identifier information userId = new URI(USER_ID); userIdType = new URI(USER_ID_TYPE); // this code doesn't do it, but this would be a good place to setup a // cache if you don't want to fetch the group information each time } /** * Sepcifies whether or not this module supports AttributeDesignator * queries. Since that's what this code does, this method always returns * true; * * @return true */ public boolean isDesignatorSupported() { return true; } /** * Specifies the types of designators this code supports. In this case, the * module supports only subject attributes. * * @return a <code>Set</code> containing the supported types */ public Set getSupportedDesignatorTypes() { Set types = new HashSet(); types.add(new Integer(AttributeDesignator.SUBJECT_TARGET)); return types; } /** * Specifies the identifiers that this code supports. This module has been * written to support exactly one attribute, but in general you could write * a module that supports any number of attributes. * * @return a <code>Set</code> specifying the supported attributes ids */ public Set getSupportedIds() { Set ids = new HashSet(); try { ids.add(new URI(SUPPORTED_ATTRIBUTE_ID)); } catch (URISyntaxException se) { // this won't actually happen in this case return null; } return ids; } /** * This is called when the PDP is trying to find a value that wasn't * included in a Request. The value that the PDP is looking for may or may * not be supported by this module, so you first have to check that you can * handle this request. */ public EvaluationResult findAttribute(URI attributeType, URI attributeId, URI issuer, URI subjectCategory, EvaluationCtx context, int designatorType) { System.out.println("AttributeType: " + attributeType.toString()); System.out.println("AttributeID: " + attributeId.toString()); // check that this is a Subject attribute if (designatorType != AttributeDesignator.SUBJECT_TARGET) return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); // check that this is the type and identifier that this module is // setup to handle if ((!attributeType.toString().equals(StringAttribute.identifier)) || (!attributeId.toString().equals(SUPPORTED_ATTRIBUTE_ID))) { return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); } // if we got here then we're looking for the one attribute that this // module knows how to handle, so get the user's identifier...note // that we don't consider the issuer here, since it pertains to the // issuer of the group values (ie, the values that this module is // supposed to return) EvaluationResult result = context.getSubjectAttribute(userIdType, userId, subjectCategory); // make sure there wasn't an error getting the identifier if (result.indeterminate()) return result; // make sure we found exactly one value for the user's identifier BagAttribute bag = (BagAttribute) (result.getAttributeValue()); if (bag.size() != 1) { ArrayList code = new ArrayList(); code.add(Status.STATUS_MISSING_ATTRIBUTE); Status status = new Status(code, attributeId.toString()); return new EvaluationResult(status); } // get the identifier out of the bag and get the group memberships RFC822NameAttribute user = (RFC822NameAttribute) (bag.iterator().next()); // return retrieveValue(attributeType, attributeId.toString()); return getGroups(user); } /** * This is the app-specific part that you need to fill in to make this * module work correctly. This method should use the user's identity to * lookup the groups that the user is in. The groups will probably be * returned either as multiple items in a bag, or as a single String listing * all the groups (depending on what your system needs). */ private EvaluationResult getGroups(RFC822NameAttribute user) { // do the group lookup...note that regardless of the form of the // groups, you must return an EvaluationResult that contains a // Bag, since that's the form that must be returned from the // findAttribute method above BagAttribute groups = null; // if there is an error at any point in this routine, then return // an EvaluationResult with status to explain the error // finally, return the group information return new EvaluationResult(groups); } private EvaluationResult retrieveValue(URI attributeType, String attributeID) { //TODO Hier die Attribute sammeln, deren Werte nicht gefunden werden konnten System.out.println("Need the attribute " + attributeID); List collection = new LinkedList(); collection.add(new StringAttribute("Blablabla")); BagAttribute groups = new BagAttribute(attributeType, collection); // if there is an error at any point in this routine, then return // an EvaluationResult with status to explain the error // finally, return the group information return new EvaluationResult(groups); } }