// // (C) Copyright 2007 VeriSign, Inc. All Rights Reserved. // // VeriSign, Inc. shall have no responsibility, financial or // otherwise, for any consequences arising out of the use of // this material. The program material is provided on an "AS IS" // BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either // express or implied. // // Distributed under an Apache License // http://www.apache.org/licenses/LICENSE-2.0 // package org.verisign.joid.extension; import org.verisign.joid.OpenIdException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Iterator; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Provider Authentication Policy Extension request message. See the * <a href="http://openid.net/specs/openid-provider-authentication-policy-extension-1_0.html">specification</a>. * <p> * Example of parsing incoming requests: * <pre> * AuthenticationRequest ar = (AuthenticationRequest) req; * PapeRequest pr = new PapeRequest(ar.getExtensions()); * if (pr.isValid()) { * ... * } * } * </pre> * </p> * * <p> * Example of inserting PAPE request to an outgoing request: * <pre> * AuthenticationRequest ar = AuthenticationRequest.create(identity, * returnTo, * trustRoot, * assocHandle); * PapeRequest pr = new PapeRequest(); * pr.setMaxAuthAge(3600); * ar.addExtension(pr); * </pre> * </p> */ public class PapeRequest extends Extension implements PapeConstants { /** * PAPE request parameter: If the End User has not actively * authenticated to the OP within the number of seconds specified * in a manner fitting the requested policies, the OP SHOULD * authenticate the End User for this request. Value: Integer * value greater than or equal to zero in seconds, and is * optional. */ static String MAX_AUTH_AGE = "max_auth_age"; /** * PAPE request parameter: Zero or more authentication policy URIs * that the OP SHOULD conform to when authenticating the user. If * multiple policies are requested, the OP SHOULD satisfy as many * as it can. */ static String PREFERRED_AUTH_POLICIES = "preferred_auth_policies"; /** * The name space for the custom Assurance Level. Assurance levels * and their name spaces are defined by various parties, such as * country or industry specific standards bodies, or other groups * or individuals. */ static String AUTH_LEVEL_NS = "auth_level.ns."; /** * A list of the name space aliases for the custom Assurance Level * name spaces that the RP requests be present in the response, in * the order of its preference. */ static String PREFERRED_AUTH_LEVELS = "preferred_auth_level_types"; /** * Construct <code>PapeRequest</code> object with the correct * namespace and an empty set of attributes. * <code>preferred_auth_policies</code> is initialized to an empty * string. */ public PapeRequest () { super(PAPE_NAMESPACE, PAPE_IDENTIFIER); // PREFERRED_AUTH_POLICIES is a mandatory parameter, default // to none setParam(PREFERRED_AUTH_POLICIES, ""); } /** * Construct <code>PapeRequest</code> object using the given * parameter mappings. Get the <code>extensionMap</code> * parameter from * <code>AuthenticationRequest.getExtensions</code>. * * @param extensionMap a <code>Map<String, String></code> containing the parameter mappings */ public PapeRequest (Map extensionMap) { super(PAPE_NAMESPACE, extensionMap); } /** * Retrieve the <code>max_auth_age</code> parameter. * * @return the maximum authentication age as an <code>Integer</code> value * @exception OpenIdException if the parameter didn't parse to an integer * @see #MAX_AUTH_AGE */ public Integer getMaxAuthAge () throws OpenIdException { return getIntParam(MAX_AUTH_AGE); } /** * Set the <code>max_auth_age</code> parameter with the given * value. * * @param age maximum authentication age as an <code>int</code> value * @see #MAX_AUTH_AGE */ public void setMaxAuthAge (int age) { setMaxAuthAge(new Integer(age)); } /** * Set the <code>max_auth_age</code> parameter with the given * value. If <code>null</code> is specified as the value, the * parameter will be removed. * * @param age maximum authentication age as an <code>Integer</code> value * @see #MAX_AUTH_AGE */ public void setMaxAuthAge (Integer age) { if (age == null) { // max_auth_age is optional, remove it if set to null clearParam(MAX_AUTH_AGE); } else { Integer minVal = new Integer(0); if (age.compareTo(minVal) < 0) { setIntParam(MAX_AUTH_AGE, minVal); } else { setIntParam(MAX_AUTH_AGE, age); } } } /** * Retrieve the <code>preferred_auth_policies</code> parameter * values. * * @return preferred authentication policies as a <code>Set<String></code> value * @see #PREFERRED_AUTH_POLICIES */ public Set getPreferredAuthPolicies () { return getSetParam(PREFERRED_AUTH_POLICIES, " "); } /** * Set the <code>preferred_auth_policies</code> parameter with the * given array of policy URI strings. Duplicate URIs will be * discarded. * * @param policies a set of policy URIs as a <code>String[]</code> value * @see #PREFERRED_AUTH_POLICIES */ public void setPreferredAuthPolicies (String[] policies) { setPreferredAuthPolicies(new LinkedHashSet(Arrays.asList(policies))); } /** * Set the <code>preferred_auth_policies</code> parameter with the * given set of policy URI strings. * * @param policies a set of policy URIs as a <code>Set<String></code> value * @see #PREFERRED_AUTH_POLICIES */ public void setPreferredAuthPolicies (Set policies) { setListParam(PREFERRED_AUTH_POLICIES, policies, " "); } /** * Retrieve the <code>auth_level_ns</code> namespaces and values. * * @return namespaces as a <code>Map<String, String></code> * @see #AUTH_LEVEL_NS */ Map getAuthLevelNS () { Map map = new HashMap(); Iterator iter = getParamMap().keySet().iterator(); while (iter.hasNext()) { String key = (String) iter.next(); int i = key.indexOf(AUTH_LEVEL_NS); if (i >= 0) { key = key.substring(i); map.put(key.substring(AUTH_LEVEL_NS.length()), getParam(key)); } } return map; } /** * Retrieve the <code>auth_level_ns</code> namespaces and values. * * @param namespace name of namespace * @return namespace value * @see #AUTH_LEVEL_NS */ String getAuthLevelNS (String namespace) { return getParam(AUTH_LEVEL_NS + namespace); } /** * Set the <code>auth_level_ns</code> namespaces and values. * * @param authLevels a set of auth level namespaces as a <code>Map<String, String></code> * @see #AUTH_LEVEL_NS */ void setAuthLevelNS (Map authLevels) { Iterator iter = authLevels.keySet().iterator(); while (iter.hasNext()) { String key = (String) iter.next(); addAuthLevelNS(key, (String) authLevels.get(key)); } } /** * Add an <code>auth_level_ns</code> namespace. * * @param namespace the name of the namespace * @param value the value of the namespace's URL identifier * @see #AUTH_LEVEL_NS */ void addAuthLevelNS (String namespace, String value) { setParam(AUTH_LEVEL_NS + namespace, value); } /** * Retrieve the <code>preferred_auth_levels</code> parameter * values. * * @return preferred authentication levels as a <code>List<String></code> value * @see #PREFERRED_AUTH_LEVELS */ List getPreferredAuthLevelNSs () { return getListParam(PREFERRED_AUTH_LEVELS, " "); } /** * Set the <code>preferred_auth_levels</code> parameter with the * given array of policy URI strings. Duplicate URIs will be * discarded. * * @param levels a set of policy URIs as a <code>String[]</code> value * @see #PREFERRED_AUTH_LEVELS */ void setPreferredAuthLevelNSs (String[] levels) { setPreferredAuthLevels(new ArrayList(Arrays.asList(levels))); } /** * Set the <code>preferred_auth_levels</code> parameter with the * given set of policy URI strings. * * @param levels a list of policy namespaces ordered by preference as a <code>List<String></code> value * @see #PREFERRED_AUTH_LEVELS */ void setPreferredAuthLevelNSs (List levels) { setListParam(PREFERRED_AUTH_LEVELS, levels, " "); } /** * Retrieve the <code>preferred_auth_levels</code> parameter * values, translated to the values in * <code>auth_level.ns.*</code>. * * @return preferred authentication levels as a <code>List<String></code> value * @see #PREFERRED_AUTH_LEVELS * @see #AUTH_LEVEL_NS */ public List getPreferredAuthLevels () { Iterator it = getPreferredAuthLevelNSs().iterator(); List levels = new ArrayList(); while (it.hasNext()) { levels.add(getAuthLevelNS((String) it.next())); } return levels; } /** * Set the <code>preferred_auth_levels</code> and * <code>auth_level.ns.*</code> parameter with the given array of * policy URI strings. Duplicate URIs will be discarded. * * @param levels a set of policy URIs as a <code>String[]</code> value * @see #PREFERRED_AUTH_LEVELS * @see #AUTH_LEVEL_NS */ public void setPreferredAuthLevels (String[] levels) { setPreferredAuthLevels(new ArrayList(Arrays.asList(levels))); } /** * Set the <code>preferred_auth_levels</code> and * <code>auth_level.ns.*</code> parameter with the given ordered * list of policy URI strings. * * @param levels a list of policy namespaces ordered by preference as a <code>List<String></code> value * @see #PREFERRED_AUTH_LEVELS * @see #AUTH_LEVEL_NS */ public void setPreferredAuthLevels (List levels) { int i = 0; List prefNS = new ArrayList(); Iterator it = levels.iterator(); while (it.hasNext()) { String level = (String) it.next(); String ns = "ns" + Integer.toString(i++, 16); addAuthLevelNS(ns, level); prefNS.add(ns); } setPreferredAuthLevelNSs(prefNS); } }