All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wss4j.dom.message.token.UsernameToken Maven / Gradle / Ivy

There is a newer version: 3.0.4
Show newest version
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.wss4j.dom.message.token;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.namespace.QName;

import org.apache.wss4j.common.bsp.BSPEnforcer;
import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl;
import org.apache.wss4j.common.util.DOM2Writer;
import org.apache.wss4j.common.util.DateUtil;
import org.apache.wss4j.common.util.KeyUtils;
import org.apache.wss4j.common.util.UsernameTokenUtil;
import org.apache.wss4j.common.util.WSCurrentTimeSource;
import org.apache.wss4j.common.util.WSTimeSource;
import org.apache.wss4j.common.util.XMLUtils;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * UsernameToken according to WS Security specifications, UsernameToken profile.
 *
 * Enhanced to support digest password type for username token signature
 * Enhanced to support passwordless usernametokens as allowed by spec.
 */
public class UsernameToken {
    public static final String BASE64_ENCODING = WSConstants.SOAPMESSAGE_NS + "#Base64Binary";
    public static final String PASSWORD_TYPE = "passwordType";
    public static final int DEFAULT_ITERATION = 1000;
    public static final QName TOKEN =
        new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN);

    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(UsernameToken.class);

    private Element element;
    private Element elementUsername;
    private Element elementPassword;
    private Element elementNonce;
    private Element elementCreated;
    private Element elementSalt;
    private Element elementIteration;
    private String passwordType;
    private boolean hashed = true;
    private String rawPassword;        // enhancement by Alberto Coletti
    private boolean passwordsAreEncoded;
    private Instant created;

    /**
     * Constructs a UsernameToken object and parses the
     * wsse:UsernameToken element to initialize it.
     *
     * @param elem the wsse:UsernameToken element that contains
     *             the UsernameToken data
     * @param allowNamespaceQualifiedPasswordTypes whether to allow (wsse)
     *        namespace qualified password types or not (for interop with WCF)
     * @param bspEnforcer a BSPEnforcer instance to enforce BSP rules
     * @throws WSSecurityException
     */
    public UsernameToken(
        Element elem,
        boolean allowNamespaceQualifiedPasswordTypes,
        BSPEnforcer bspEnforcer
    ) throws WSSecurityException {
        element = elem;
        QName el = new QName(element.getNamespaceURI(), element.getLocalName());
        if (!el.equals(TOKEN)) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
                "badElement",
                new Object[] {TOKEN, el}
            );
        }
        elementUsername =
            XMLUtils.getDirectChildElement(
                element, WSConstants.USERNAME_LN, WSConstants.WSSE_NS
            );
        elementPassword =
            XMLUtils.getDirectChildElement(
                element, WSConstants.PASSWORD_LN, WSConstants.WSSE_NS
            );
        elementNonce =
            XMLUtils.getDirectChildElement(
                element, WSConstants.NONCE_LN, WSConstants.WSSE_NS
            );
        elementCreated =
            XMLUtils.getDirectChildElement(
                element, WSConstants.CREATED_LN, WSConstants.WSU_NS
            );
        elementSalt =
            XMLUtils.getDirectChildElement(
                element, WSConstants.SALT_LN, WSConstants.WSSE11_NS
            );
        elementIteration =
            XMLUtils.getDirectChildElement(
                element, WSConstants.ITERATION_LN, WSConstants.WSSE11_NS
            );
        if (elementUsername == null) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
                "badUsernameToken",
                new Object[] {"Username is missing"}
            );
        }

        checkBSPCompliance(bspEnforcer);

        hashed = false;
        if (elementSalt != null) {
            //
            // If the UsernameToken is to be used for key derivation, the (1.1)
            // spec says that it cannot contain a password, and it must contain
            // an Iteration element
            //
            if (elementPassword != null || elementIteration == null) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
                    "badUsernameToken",
                    new Object[] {"Password is missing"}
                );
            }
            return;
        }

        // Guard against a malicious user sending a bogus iteration value
        if (elementIteration != null) {
            String iter = XMLUtils.getElementText(elementIteration);
            if (iter != null) {
                int iterInt = Integer.parseInt(iter);
                if (iterInt < 0 || iterInt > 10000) {
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
                        "badUsernameToken",
                        new Object[] {"Iteration is missing"}
                    );
                }
            }
        }

        if (elementPassword != null) {
            if (elementPassword.hasAttributeNS(null, WSConstants.PASSWORD_TYPE_ATTR)) {
                passwordType = elementPassword.getAttributeNS(null, WSConstants.PASSWORD_TYPE_ATTR);
            } else if (elementPassword.hasAttributeNS(
                WSConstants.WSSE_NS, WSConstants.PASSWORD_TYPE_ATTR)
            ) {
                if (allowNamespaceQualifiedPasswordTypes) {
                    passwordType =
                        elementPassword.getAttributeNS(
                            WSConstants.WSSE_NS, WSConstants.PASSWORD_TYPE_ATTR
                        );
                } else {
                    throw new WSSecurityException(
                        WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
                        "badUsernameToken",
                        new Object[] {"The Password Type is not allowed to be namespace qualified"}
                    );
                }
            }

        }
        if (WSConstants.PASSWORD_DIGEST.equals(passwordType)) {
            hashed = true;
            if (elementNonce == null || elementCreated == null) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN,
                    "badUsernameToken",
                    new Object[] {"Nonce or Created is missing"}
                );
            }
        }

        if (elementCreated != null) {
            String createdString = getCreated();
            if (createdString != null && !"".equals(createdString)) {
                try {
                    created = ZonedDateTime.parse(createdString).toInstant();
                } catch (DateTimeParseException e) {
                    throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
                }
            }
        }
    }

    /**
     * Constructs a UsernameToken object according to the defined
     * parameters. 

This constructs set the password encoding to * {@link WSConstants#PASSWORD_DIGEST} * * @param doc the SOAP envelope as Document */ public UsernameToken(boolean milliseconds, Document doc) { this(milliseconds, doc, WSConstants.PASSWORD_DIGEST); } /** * Constructs a UsernameToken object according to the defined * parameters. * * @param doc the SOAP envelope as Document * @param pwType the required password encoding, either * {@link WSConstants#PASSWORD_DIGEST} or * {@link WSConstants#PASSWORD_TEXT} or * {@link WSConstants#PW_NONE} null if no * password required */ public UsernameToken(boolean milliseconds, Document doc, String pwType) { this(milliseconds, doc, new WSCurrentTimeSource(), pwType); } public UsernameToken(boolean milliseconds, Document doc, WSTimeSource timeSource, String pwType) { element = doc.createElementNS(WSConstants.WSSE_NS, "wsse:" + WSConstants.USERNAME_TOKEN_LN); elementUsername = doc.createElementNS(WSConstants.WSSE_NS, "wsse:" + WSConstants.USERNAME_LN); elementUsername.appendChild(doc.createTextNode("")); element.appendChild(elementUsername); if (pwType != null) { elementPassword = doc.createElementNS(WSConstants.WSSE_NS, "wsse:" + WSConstants.PASSWORD_LN); elementPassword.appendChild(doc.createTextNode("")); element.appendChild(elementPassword); passwordType = pwType; if (passwordType.equals(WSConstants.PASSWORD_DIGEST)) { addNonce(doc); addCreated(milliseconds, timeSource, doc); } else { hashed = false; } } } /** * Add the WSSE Namespace to this UT. The namespace is not added by default for * efficiency purposes. */ public void addWSSENamespace() { XMLUtils.setNamespace(element, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX); } /** * Add the WSU Namespace to this UT. The namespace is not added by default for * efficiency purposes. */ public void addWSUNamespace() { XMLUtils.setNamespace(element, WSConstants.WSU_NS, WSConstants.WSU_PREFIX); } /** * Creates and adds a Nonce element to this UsernameToken */ public void addNonce(Document doc) { if (elementNonce != null) { return; } byte[] nonceValue = null; try { nonceValue = WSSecurityUtil.generateNonce(16); } catch (WSSecurityException ex) { LOG.debug(ex.getMessage(), ex); return; } elementNonce = doc.createElementNS(WSConstants.WSSE_NS, "wsse:" + WSConstants.NONCE_LN); elementNonce.appendChild(doc.createTextNode(org.apache.xml.security.utils.XMLUtils.encodeToString(nonceValue))); elementNonce.setAttributeNS(null, "EncodingType", BASE64_ENCODING); element.appendChild(elementNonce); } /** * Creates and adds a Created element to this UsernameToken */ public void addCreated(boolean milliseconds, Document doc) { addCreated(milliseconds, new WSCurrentTimeSource(), doc); } /** * Creates and adds a Created element to this UsernameToken */ public void addCreated(boolean milliseconds, WSTimeSource timeSource, Document doc) { if (elementCreated != null) { return; } elementCreated = doc.createElementNS( WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN ); Instant currentTime = timeSource.now(); DateTimeFormatter formatter = DateUtil.getDateTimeFormatter(milliseconds); elementCreated.appendChild(doc.createTextNode(currentTime.atZone(ZoneOffset.UTC).format(formatter))); element.appendChild(elementCreated); } /** * Adds and optionally creates a Salt element to this UsernameToken. * * If the saltValue is null the the method * generates a new salt. Otherwise it uses the the given value. * * @param doc The Document for the UsernameToken * @param saltValue The salt to add, if null generate a new salt value * @param mac If true then an optionally generated value is * usable for a MAC * @return Returns the added salt */ public byte[] addSalt(Document doc, byte[] saltValue, boolean mac) { if (saltValue == null) { saltValue = UsernameTokenUtil.generateSalt(mac); } elementSalt = doc.createElementNS( WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX + ":" + WSConstants.SALT_LN ); XMLUtils.setNamespace(element, WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX); elementSalt.appendChild(doc.createTextNode(org.apache.xml.security.utils.XMLUtils.encodeToString(saltValue))); element.appendChild(elementSalt); return saltValue; } /** * Creates and adds a Iteration element to this UsernameToken */ public void addIteration(Document doc, int iteration) { String text = "" + iteration; elementIteration = doc.createElementNS( WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX + ":" + WSConstants.ITERATION_LN ); XMLUtils.setNamespace(element, WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX); elementIteration.appendChild(doc.createTextNode(text)); element.appendChild(elementIteration); } /** * Get the user name. * * @return the data from the user name element. */ public String getName() { return XMLUtils.getElementText(elementUsername); } /** * Set the user name. * * @param name sets a text node containing the use name into the user name * element. */ public void setName(String name) { Text node = getFirstNode(elementUsername); node.setData(name); } /** * Get the nonce. * * @return the data from the nonce element. */ public String getNonce() { return XMLUtils.getElementText(elementNonce); } /** * Get the created timestamp. * * @return the data from the created time element. */ public String getCreated() { return XMLUtils.getElementText(elementCreated); } /** * Return the Created Element as a Date object * @return the Created Date */ public Instant getCreatedDate() { return created; } /** * Gets the password string. This is the password as it is in the password * element of a username token. Thus it can be either plain text or the * password digest value. * * @return the password string or null if no such node exists. */ public String getPassword() { String password = XMLUtils.getElementText(elementPassword); // See WSS-219 if (password == null && elementPassword != null) { return ""; } return password; } /** * Return true if this UsernameToken contains a Password element */ public boolean containsPasswordElement() { return elementPassword != null; } /** * Get the Salt value of this UsernameToken. * * @return Returns the binary Salt value or null if no Salt * value is available in the username token. * @throws WSSecurityException */ public byte[] getSalt() throws WSSecurityException { String salt = XMLUtils.getElementText(elementSalt); if (salt != null) { return org.apache.xml.security.utils.XMLUtils.decode(salt); } return null; } /** * Get the Iteration value of this UsernameToken. * * @return Returns the Iteration value. If no Iteration was specified in the * username token the default value according to the specification * is returned. */ public int getIteration() { String iter = XMLUtils.getElementText(elementIteration); if (iter != null) { return Integer.parseInt(iter); } return DEFAULT_ITERATION; } /** * Get the hashed indicator. If the indicator is true> the password of the * UsernameToken was encoded using {@link WSConstants#PASSWORD_DIGEST} * * @return the hashed indicator. */ public boolean isHashed() { return hashed; } /** * @return Returns the passwordType. */ public String getPasswordType() { return passwordType; } /** * Sets the password string. This function sets the password in the * UsernameToken either as plain text or encodes the password * according to the WS Security specifications, UsernameToken profile, into * a password digest. * * @param pwd the password to use */ public void setPassword(String pwd) { if (pwd == null) { if (passwordType != null) { throw new IllegalArgumentException("pwd == null but a password is needed"); } else { // Ignore setting the password. return; } } rawPassword = pwd; // enhancement by Alberto coletti Text node = getFirstNode(elementPassword); try { if (hashed) { if (passwordsAreEncoded) { node.setData(doPasswordDigest(getNonce(), getCreated(), org.apache.xml.security.utils.XMLUtils.decode(pwd))); } else { node.setData(doPasswordDigest(getNonce(), getCreated(), pwd)); } } else { node.setData(pwd); } if (passwordType != null) { elementPassword.setAttributeNS(null, "Type", passwordType); } } catch (Exception e) { LOG.debug(e.getMessage(), e); } } /** * Set the raw (plain text) password used to compute secret key. */ public void setRawPassword(CallbackHandler callbackHandler) throws WSSecurityException { if (callbackHandler == null) { LOG.debug("CallbackHandler is null"); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION); } WSPasswordCallback pwCb = new WSPasswordCallback( getName(), getPassword(), getPasswordType(), WSPasswordCallback.USERNAME_TOKEN ); try { callbackHandler.handle(new Callback[]{pwCb}); } catch (IOException | UnsupportedCallbackException e) { LOG.debug(e.getMessage(), e); throw new WSSecurityException( WSSecurityException.ErrorCode.FAILED_AUTHENTICATION, e ); } rawPassword = pwCb.getPassword(); } /** * @param passwordsAreEncoded whether passwords are encoded */ public void setPasswordsAreEncoded(boolean passwordsAreEncoded) { this.passwordsAreEncoded = passwordsAreEncoded; } /** * @return whether passwords are encoded */ public boolean getPasswordsAreEncoded() { return passwordsAreEncoded; } public static String doPasswordDigest(String nonce, String created, byte[] password) { String passwdDigest = null; try { byte[] b1 = nonce != null ? org.apache.xml.security.utils.XMLUtils.decode(nonce) : new byte[0]; byte[] b2 = created != null ? created.getBytes(StandardCharsets.UTF_8) : new byte[0]; byte[] b3 = password; byte[] b4 = new byte[b1.length + b2.length + b3.length]; int offset = 0; System.arraycopy(b1, 0, b4, offset, b1.length); offset += b1.length; System.arraycopy(b2, 0, b4, offset, b2.length); offset += b2.length; System.arraycopy(b3, 0, b4, offset, b3.length); byte[] digestBytes = KeyUtils.generateDigest(b4); passwdDigest = org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes); } catch (Exception e) { LOG.debug(e.getMessage(), e); } return passwdDigest; } public static String doPasswordDigest(String nonce, String created, String password) { String passwdDigest = null; try { passwdDigest = doPasswordDigest(nonce, created, password.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { LOG.debug(e.getMessage(), e); } return passwdDigest; } /** * Returns the first text node of an element. * * @param e the element to get the node from * @return the first text node or null if node is null or is * not a text node */ private Text getFirstNode(Element e) { Node node = e.getFirstChild(); return node != null && Node.TEXT_NODE == node.getNodeType() ? (Text) node : null; } /** * Returns the dom element of this UsernameToken object. * * @return the wsse:UsernameToken element */ public Element getElement() { return element; } /** * Returns the string representation of the token. * * @return a XML string representation */ public String toString() { return DOM2Writer.nodeToString(element); } /** * Gets the id. * * @return the value of the wsu:Id attribute of this username * token */ public String getID() { return element.getAttributeNS(WSConstants.WSU_NS, "Id"); } /** * Set the id of this username token. * * @param id * the value for the wsu:Id attribute of this * username token */ public void setID(String id) { element.setAttributeNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":Id", id); } /** * This method gets a derived key as defined in WSS Username Token Profile. * * @return Returns the derived key as a byte array * @throws WSSecurityException */ public byte[] getDerivedKey(BSPEnforcer bspEnforcer) throws WSSecurityException { if (rawPassword == null) { LOG.debug("The raw password was null"); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION); } if (elementSalt == null) { // We must have a salt element to use this token for a derived key bspEnforcer.handleBSPRule(BSPRule.R4217); } if (elementIteration == null) { // we must have an iteration element to use this token for a derived key bspEnforcer.handleBSPRule(BSPRule.R4218); } else { String iter = XMLUtils.getElementText(elementIteration); if (iter == null || Integer.parseInt(iter) < 1000) { bspEnforcer.handleBSPRule(BSPRule.R4218); } } int iteration = getIteration(); byte[] salt = getSalt(); if (passwordsAreEncoded) { return UsernameTokenUtil.generateDerivedKey(org.apache.xml.security.utils.XMLUtils.decode(rawPassword), salt, iteration); } else { return UsernameTokenUtil.generateDerivedKey(rawPassword, salt, iteration); } } /** * Return whether the UsernameToken represented by this class is to be used * for key derivation as per the UsernameToken Profile 1.1. It does this by * checking that the username token has salt and iteration values. * * @throws WSSecurityException */ public boolean isDerivedKey() throws WSSecurityException { if (elementSalt != null && elementIteration != null) { return true; } return false; } /** * Create a WSUsernameTokenPrincipal from this UsernameToken object */ public Principal createPrincipal() throws WSSecurityException { WSUsernameTokenPrincipalImpl principal = new WSUsernameTokenPrincipalImpl(getName(), isHashed()); String nonce = getNonce(); if (nonce != null) { principal.setNonce(org.apache.xml.security.utils.XMLUtils.decode(nonce)); } principal.setPassword(getPassword()); principal.setCreatedTime(getCreated()); return principal; } /** * Return true if the "Created" value is before the current time minus the timeToLive * argument, and if the Created value is not "in the future". * * @param timeToLive the value in seconds for the validity of the Created time * @param futureTimeToLive the value in seconds for the future validity of the Created time * @return true if the UsernameToken is before (now-timeToLive), false otherwise */ public boolean verifyCreated( int timeToLive, int futureTimeToLive ) { return DateUtil.verifyCreated(created, timeToLive, futureTimeToLive); } @Override public int hashCode() { int result = 17; String username = getName(); if (username != null) { result = 31 * result + username.hashCode(); } String password = getPassword(); if (password != null) { result = 31 * result + password.hashCode(); } String passwordType = getPasswordType(); if (passwordType != null) { result = 31 * result + passwordType.hashCode(); } String nonce = getNonce(); if (nonce != null) { result = 31 * result + nonce.hashCode(); } String created = getCreated(); if (created != null) { result = 31 * result + created.hashCode(); } try { byte[] salt = getSalt(); if (salt != null) { result = 31 * result + Arrays.hashCode(salt); } } catch (WSSecurityException ex) { LOG.debug(ex.getMessage(), ex); } result = 31 * result + Integer.valueOf(getIteration()).hashCode(); return result; } @Override public boolean equals(Object object) { if (!(object instanceof UsernameToken)) { return false; } UsernameToken usernameToken = (UsernameToken)object; if (!compare(usernameToken.getName(), getName())) { return false; } if (!compare(usernameToken.getPassword(), getPassword())) { return false; } if (!compare(usernameToken.getPasswordType(), getPasswordType())) { return false; } if (!compare(usernameToken.getNonce(), getNonce())) { return false; } if (!compare(usernameToken.getCreated(), getCreated())) { return false; } try { byte[] salt = usernameToken.getSalt(); if (!Arrays.equals(salt, getSalt())) { return false; } } catch (WSSecurityException ex) { LOG.debug(ex.getMessage(), ex); } int iteration = usernameToken.getIteration(); if (iteration != getIteration()) { return false; } return true; } private boolean compare(String item1, String item2) { if (item1 == null && item2 != null) { return false; } else if (item1 != null && !item1.equals(item2)) { return false; } return true; } /** * A method to check that the UsernameToken is compliant with the BSP spec. * @throws WSSecurityException */ private void checkBSPCompliance(BSPEnforcer bspEnforcer) throws WSSecurityException { List passwordElements = WSSecurityUtil.getDirectChildElements( element, WSConstants.PASSWORD_LN, WSConstants.WSSE_NS ); // We can only have one password element if (passwordElements.size() > 1) { LOG.debug("The Username Token had more than one password element"); bspEnforcer.handleBSPRule(BSPRule.R4222); } // We must have a password type if (passwordElements.size() == 1) { Element passwordChild = passwordElements.get(0); String type = passwordChild.getAttributeNS(null, WSConstants.PASSWORD_TYPE_ATTR); if (type == null || "".equals(type)) { LOG.debug("The Username Token password does not have a Type attribute"); bspEnforcer.handleBSPRule(BSPRule.R4201); } } List createdElements = WSSecurityUtil.getDirectChildElements( element, WSConstants.CREATED_LN, WSConstants.WSU_NS ); // We can only have one created element if (createdElements.size() > 1) { LOG.debug("The Username Token has more than one created element"); bspEnforcer.handleBSPRule(BSPRule.R4223); } List nonceElements = WSSecurityUtil.getDirectChildElements( element, WSConstants.NONCE_LN, WSConstants.WSSE_NS ); // We can only have one nonce element if (nonceElements.size() > 1) { LOG.debug("The Username Token has more than one nonce element"); bspEnforcer.handleBSPRule(BSPRule.R4225); } if (nonceElements.size() == 1) { Element nonce = nonceElements.get(0); String encodingType = nonce.getAttributeNS(null, "EncodingType"); // Encoding Type must be equal to Base64Binary if (encodingType == null || "".equals(encodingType)) { bspEnforcer.handleBSPRule(BSPRule.R4220); } else if (!WSConstants.BASE64_ENCODING.equals(encodingType)) { LOG.debug("The Username Token's nonce element has a bad encoding type"); bspEnforcer.handleBSPRule(BSPRule.R4221); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy