a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: DefaultSPAuthnContextMapper.java,v 1.9 2008/11/10 22:57:02 veiming Exp $
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.AuthnContext;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.ProtocolFactory;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.RequestedAuthnContext;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Constants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Exception;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Utils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.profile.SPSSOFederate;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.encode.URLEncDec;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The <code>DefaultSPAuthnContextMapper.java</code> class determines
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the authentication context and the authentication requirements for
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * authentication by the authenticaion authority.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This implementation only uses Authentication Class Reference.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The Authentication Class Reference can be passed as a query parameter
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * or set in the SP Entity Configuration.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class DefaultSPAuthnContextMapper implements SPAuthnContextMapper {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static String DEFAULT_CLASS_REF = "defaultClassRef";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the <code>RequestedAuthnContext</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The RequestedAuthContext is created based on the query parameters
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * AuthnContextClassRef and AuthComparison in the request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * and authnContext attribute ,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * spAuthncontextClassrefMapping, and authComparison
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * attribute, spAuthncontextComparisonType ,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * set in the Service Provider Extended Configuration.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If the AuthnContext Class Reference cannot be determined then
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the default value
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTranstport
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * will be used. AuthnComparsion defaults to "exact" if no value
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is specified.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param realm Realm or Organization of the Service Provider.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostEntityID Entity ID of the Service Provider.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param paramsMap Map containing key/value pairs of parameters.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The key/value pairs are those accepted during SP SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * initiation.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAML2Exception if an error occurs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public RequestedAuthnContext getRequestedAuthnContext(String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Read the AuthnContext Class Reference passed as query string
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (List) paramsMap.get(SAML2Constants.AUTH_CONTEXT_CLASS_REF);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ((List)paramsMap.get(SAML2Constants.AUTH_LEVEL));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authLevelList != null && !authLevelList.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster new Integer((String) authLevelList.iterator().next());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("not a valid integer",nfe);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "integer object",e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("authLevel in Query:"+ authLevel);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("authContextClassRef in Query:"+
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Retreived the cached AuthClass Ref / Auth Level Map
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map authRefMap = getAuthRefMap(realm, hostEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // create a List of AuthnContext Class Reference
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authContextClassRef != null && !authContextClassRef.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (i.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authClassRef = prefixIfRequired((String) i.next());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (i.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Integer aLevel = (Integer)authRefMap.get(className);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authCtxList == null || authCtxList.isEmpty())
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String defaultClassRef = (String) authRefMap.get(DEFAULT_CLASS_REF);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (i.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // if list empty set the default
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Constants.CLASSREF_PASSWORD_PROTECTED_TRANSPORT);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("SPCache.authContextHash is: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("authCtxList is: "+ authCtxList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Retrieve Auth Comparison from Query parameter
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authCtxComparison = SPSSOFederate.getParameter(paramsMap,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("AuthComparison in Query:"+
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authCtxComparison = SAML2Utils.getAttributeValueFromSSOConfig(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Constants.SP_AUTHCONTEXT_COMPARISON_TYPE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ProtocolFactory.getInstance().createRequestedAuthnContext();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the auth level from advice.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The advice is passed in through paramsMap as follows:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Key: Value:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * sunamcompositeadvice URLEncoded XML blob that specifies auth level
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * advice. Here is an example of the xml blob:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <AttributeValuePair>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <Attribute name="AuthLevelConditionAdvice"/>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <Value>/:1</Value>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * </AttributeValuePair>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * In this advice, the requested auth level is 1.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Note: The ":" before auth level 1 is a must.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private Integer getAuthLevelFromAdvice(Map paramsMap) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List advices = (List) paramsMap.get(SAML2Constants.AUTH_LEVEL_ADVICE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "DefaultSPAuthnContextMapper:adviceXML=" + adviceXML);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // parse xml
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Node adviceNode = XMLUtils.getRootNode(document, "Advices");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map advicePair = XMLUtils.parseAttributeValuePairTags(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "AuthLevelConditionAdvice");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authLevelvalues != null) && (!authLevelvalues.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the lowest auth level from the given set
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authLevelvalue != null && authLevelvalue.length() != 0){
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (level == null || level.compareTo(authLevel) > 0)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the auth level for the AuthContext
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param reqCtx the RequestedAuthContext object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param authnContext the AuthnContext object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param realm the realm or organization to
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * retreive the authncontext.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostEntityID the Service Provider Identity String.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the Identity Provider Identity String.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return authlevel an integer value.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAML2Exception if there is an error.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public int getAuthLevel(RequestedAuthnContext reqCtx,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (Map) SPCache.authContextHash.get(hostEntityID+"|"+realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authRefMap == null || authRefMap.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authRefMap = getAuthRefMap(realm,hostEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper:hostEntityID:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper:realm:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper:MAP:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper:HASH:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnClassRef = authnContext.getAuthnContextClassRef();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((reqCtx != null) && (authnClassRef != null) &&
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (!isAuthnContextMatching(reqCtx.getAuthnContextClassRef(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnClassRef, reqCtx.getComparison(), realm, hostEntityID))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "invalidAuthnContextClassRef"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authnClassRef != null) && (authnClassRef.length() > 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authRefMap != null) && (!authRefMap.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authLevelInt = (Integer)authRefMap.get(authnClassRef);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authRefMap != null) && (!authRefMap.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authLevelInt = (Integer)authRefMap.get(DEFAULT);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper:authnClRef:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper:authLevel :"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns true if the specified AuthnContextClassRef matches a list of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * requested AuthnContextClassRef.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param requestedACClassRefs a list of requested AuthnContextClassRef's
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param acClassRef AuthnContextClassRef
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param comparison the type of comparison
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param realm Realm or Organization of the Service Provider.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostEntityID Entity ID of the Service Provider.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return true if the specified AuthnContextClassRef matches a list of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * requested AuthnContextClassRef
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public boolean isAuthnContextMatching(List requestedACClassRefs,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acClassRef, String comparison, String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map authRefMap = getAuthRefMap(realm, hostEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return SAML2Utils.isAuthnContextMatching(requestedACClassRefs,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* parses the AuthContext attribute to get the Class Reference and
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Map getAuthnCtxFromSPConfig(String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.getAllAttributeValueFromSSOConfig(realm, hostEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Constants.SP_AUTH_CONTEXT_CLASS_REF_ATTR);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper: List:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator i = authContextClassRefConfig.iterator();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (i.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean isDefault = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringTokenizer st = new StringTokenizer(authRefVal,"|");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e ) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("AuthnContextClassRef "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "not found");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "DefaultSPAuthnContextMapper." +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "DefaultSPAuthnContextMapper." +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "getAuthnCtxFromSPConfig: AuthLevel is " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isDefault && (!authRefMap.containsKey(DEFAULT))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DEFAULT_CLASS_REF, prefixIfRequired(authClass));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return Collections.unmodifiableMap(authRefMap);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* checks for validity of authcomparision */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean isValidAuthComparison(String authComparison) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* returns a Map with key as the hostEntityID|realm and value the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the SP Extended configuration attributes.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Map getAuthRefMap(String realm,String hostEntityID) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map authRefMap = (Map)SPCache.authContextHash.get(key);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authRefMap = (Map)getAuthnCtxFromSPConfig(realm, hostEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authRefMap != null) && (!authRefMap.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e ) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("DefaultSPAuthnContextMapper." +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "getAuthRefMap:", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Adds prefix to the authn class reference only when there is
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * no ":" present.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static String prefixIfRequired(String authClassRef) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authClassRef != null) && (authClassRef.indexOf(':') == -1)) {