blob: 1695f5755d0120c6718889204ed1b5680d551d5e [file] [log] [blame]
/**
* 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.cxf.fediz.core.processor;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.Certificate;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.servlet.http.HttpServletRequest;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.cxf.fediz.core.FederationConstants;
import org.apache.cxf.fediz.core.RequestState;
import org.apache.cxf.fediz.core.TokenValidator;
import org.apache.cxf.fediz.core.TokenValidatorRequest;
import org.apache.cxf.fediz.core.TokenValidatorResponse;
import org.apache.cxf.fediz.core.config.FederationProtocol;
import org.apache.cxf.fediz.core.config.FedizContext;
import org.apache.cxf.fediz.core.config.KeyManager;
import org.apache.cxf.fediz.core.exception.ProcessingException;
import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
import org.apache.cxf.fediz.core.metadata.MetadataWriter;
import org.apache.cxf.fediz.core.spi.FreshnessCallback;
import org.apache.cxf.fediz.core.spi.HomeRealmCallback;
import org.apache.cxf.fediz.core.spi.SignInQueryCallback;
import org.apache.cxf.fediz.core.spi.WAuthCallback;
import org.apache.cxf.fediz.core.spi.WReqCallback;
import org.apache.cxf.fediz.core.util.DOMUtils;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
import org.apache.wss4j.common.util.DOM2Writer;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSDataRef;
import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.engine.WSSConfig;
import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.processor.EncryptedDataProcessor;
import org.apache.wss4j.dom.processor.Processor;
import org.apache.wss4j.dom.util.XmlSchemaDateFormat;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FederationProcessorImpl extends AbstractFedizProcessor {
private static final Logger LOG = LoggerFactory.getLogger(FederationProcessorImpl.class);
static {
WSSConfig.init();
}
/**
* Default constructor
*/
public FederationProcessorImpl() {
super();
}
@Override
public FedizResponse processRequest(FedizRequest request, FedizContext config) throws ProcessingException {
if (!(config.getProtocol() instanceof FederationProtocol)) {
LOG.error("Unsupported protocol");
throw new IllegalStateException("Unsupported protocol");
}
FedizResponse response = null;
if (FederationConstants.ACTION_SIGNIN.equals(request.getAction())) {
response = this.processSignInRequest(request, config);
} else {
LOG.error("Invalid action '" + request.getAction() + "'");
throw new ProcessingException(TYPE.INVALID_REQUEST);
}
return response;
}
public Document getMetaData(HttpServletRequest request, FedizContext config) throws ProcessingException {
return new MetadataWriter().getMetaData(request, config);
}
protected FedizResponse processSignInRequest(FedizRequest request, FedizContext config) throws ProcessingException {
Document doc = null;
Element el = null;
try {
doc = DOMUtils.readXml(new StringReader(request.getResponseToken()));
el = doc.getDocumentElement();
} catch (Exception e) {
LOG.warn("Failed to parse wresult: " + e.getMessage());
throw new ProcessingException(TYPE.INVALID_REQUEST);
}
if ("RequestSecurityTokenResponseCollection".equals(el.getLocalName())) {
el = DOMUtils.getFirstElement(el);
}
if (!"RequestSecurityTokenResponse".equals(el.getLocalName())) {
LOG.warn("Unexpected root element of wresult: '" + el.getLocalName() + "'");
throw new ProcessingException(TYPE.INVALID_REQUEST);
}
el = DOMUtils.getFirstElement(el);
Element rst = null;
Element lifetimeElem = null;
String tt = null;
while (el != null) {
String ln = el.getLocalName();
if (FederationConstants.WS_TRUST_13_NS.equals(el.getNamespaceURI())
|| FederationConstants.WS_TRUST_2005_02_NS.equals(el.getNamespaceURI())) {
if ("Lifetime".equals(ln)) {
lifetimeElem = el;
} else if ("RequestedSecurityToken".equals(ln)) {
rst = DOMUtils.getFirstElement(el);
} else if ("TokenType".equals(ln)) {
tt = DOMUtils.getContent(el);
}
}
el = DOMUtils.getNextElement(el);
}
if (LOG.isDebugEnabled()) {
if (rst != null) {
LOG.debug("RST: {}", DOM2Writer.nodeToString(rst));
}
if (lifetimeElem != null) {
LOG.debug("Lifetime: {}", DOM2Writer.nodeToString(lifetimeElem));
}
}
LOG.debug("Tokentype: {}", tt);
if (rst == null) {
LOG.warn("RequestedSecurityToken element not found in wresult");
throw new ProcessingException(TYPE.BAD_REQUEST);
}
LifeTime lifeTime = null;
if (lifetimeElem != null) {
lifeTime = processLifeTime(lifetimeElem);
}
if (lifeTime != null) {
Date currentDate = new Date();
if (currentDate.after(lifeTime.getExpires())) {
LOG.warn("RSTR Lifetime expired");
throw new ProcessingException(TYPE.TOKEN_EXPIRED);
}
DateTime currentTime = new DateTime();
DateTime validFrom = new DateTime(lifeTime.created);
currentTime = currentTime.plusSeconds(config.getMaximumClockSkew().intValue());
if (validFrom.isAfter(currentTime)) {
LOG.debug("RSTR Lifetime not yet valid");
throw new ProcessingException(TYPE.TOKEN_INVALID);
}
}
// Check to see if RST is encrypted
if ("EncryptedData".equals(rst.getLocalName()) && WSConstants.ENC_NS.equals(rst.getNamespaceURI())) {
Element decryptedRST = decryptEncryptedRST(rst, config);
if (decryptedRST != null) {
rst = decryptedRST;
}
}
TokenValidatorResponse validatorResponse = validateToken(rst, tt, config, request.getCerts());
// Check whether token already used for signin
Date expires = null;
if (lifeTime != null && lifeTime.getExpires() != null) {
expires = lifeTime.getExpires();
} else {
expires = validatorResponse.getExpires();
}
testForReplayAttack(validatorResponse.getUniqueTokenId(), config, expires);
testForMandatoryClaims(((FederationProtocol)config.getProtocol()).getRoleURI(),
((FederationProtocol)config.getProtocol()).getClaimTypesRequested(),
validatorResponse.getClaims(),
validatorResponse.getRoles() != null && !validatorResponse.getRoles().isEmpty());
Date created = validatorResponse.getCreated();
if (lifeTime != null && lifeTime.getCreated() != null) {
created = lifeTime.getCreated();
}
FedizResponse fedResponse = new FedizResponse(validatorResponse.getUsername(), validatorResponse.getIssuer(),
validatorResponse.getRoles(), validatorResponse.getClaims(),
validatorResponse.getAudience(), created, expires, rst,
validatorResponse.getUniqueTokenId());
return fedResponse;
}
private TokenValidatorResponse validateToken(Element token, String tokenType, FedizContext config,
Certificate[] certs) throws ProcessingException {
TokenValidatorResponse validatorResponse = null;
List<TokenValidator> validators = ((FederationProtocol)config.getProtocol()).getTokenValidators();
for (TokenValidator validator : validators) {
boolean canHandle = false;
if (tokenType != null) {
canHandle = validator.canHandleTokenType(tokenType);
} else {
canHandle = validator.canHandleToken(token);
}
if (canHandle) {
try {
TokenValidatorRequest validatorRequest = new TokenValidatorRequest(token, certs);
validatorResponse = validator.validateAndProcessToken(validatorRequest, config);
} catch (ProcessingException ex) {
throw ex;
} catch (Exception ex) {
LOG.warn("Failed to validate token", ex);
throw new ProcessingException(TYPE.TOKEN_INVALID);
}
break;
} else {
LOG.warn("No security token validator found for '" + tokenType + "'");
throw new ProcessingException(TYPE.BAD_REQUEST);
}
}
return validatorResponse;
}
private Element decryptEncryptedRST(Element encryptedRST, FedizContext config) throws ProcessingException {
KeyManager decryptionKeyManager = config.getDecryptionKey();
if (decryptionKeyManager == null || decryptionKeyManager.getCrypto() == null) {
LOG.debug("We must have a decryption Crypto instance configured to decrypt encrypted tokens");
throw new ProcessingException(TYPE.BAD_REQUEST);
}
String keyPassword = decryptionKeyManager.getKeyPassword();
if (keyPassword == null) {
LOG.debug("We must have a decryption key password to decrypt encrypted tokens");
throw new ProcessingException(TYPE.BAD_REQUEST);
}
EncryptedDataProcessor proc = new EncryptedDataProcessor();
WSDocInfo docInfo = new WSDocInfo(encryptedRST.getOwnerDocument());
RequestData data = new RequestData();
// Disable WSS4J processing of the (decrypted) SAML Token
WSSConfig wssConfig = WSSConfig.getNewInstance();
wssConfig.setProcessor(WSConstants.SAML_TOKEN, new NOOpProcessor());
wssConfig.setProcessor(WSConstants.SAML2_TOKEN, new NOOpProcessor());
data.setWssConfig(wssConfig);
data.setDecCrypto(decryptionKeyManager.getCrypto());
data.setCallbackHandler(new DecryptionCallbackHandler(keyPassword));
try {
List<WSSecurityEngineResult> result = proc.handleToken(encryptedRST, data, docInfo);
if (result.size() > 0) {
@SuppressWarnings("unchecked")
List<WSDataRef> dataRefs = (List<WSDataRef>)result.get(result.size() - 1)
.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
if (dataRefs != null && dataRefs.size() > 0) {
return dataRefs.get(0).getProtectedElement();
}
}
} catch (WSSecurityException e) {
LOG.debug(e.getMessage(), e);
throw new ProcessingException(TYPE.TOKEN_INVALID);
}
return null;
}
private LifeTime processLifeTime(Element lifetimeElem) throws ProcessingException {
try {
Element createdElem = DOMUtils.getFirstChildWithName(lifetimeElem, WSConstants.WSU_NS,
WSConstants.CREATED_LN);
DateFormat zulu = new XmlSchemaDateFormat();
Date created = zulu.parse(DOMUtils.getContent(createdElem));
Element expiresElem = DOMUtils.getFirstChildWithName(lifetimeElem, WSConstants.WSU_NS,
WSConstants.EXPIRES_LN);
Date expires = zulu.parse(DOMUtils.getContent(expiresElem));
return new LifeTime(created, expires);
} catch (ParseException e) {
LOG.error("Failed to parse lifetime element in wresult: {}", e.getMessage());
throw new ProcessingException(TYPE.BAD_REQUEST);
}
}
public class LifeTime {
private Date created;
private Date expires;
public LifeTime(Date created, Date expires) {
this.created = created;
this.expires = expires;
}
public Date getCreated() {
return created;
}
public Date getExpires() {
return expires;
}
}
@Override
public RedirectionResponse createSignInRequest(HttpServletRequest request, FedizContext config)
throws ProcessingException {
String redirectURL = null;
RequestState requestState = null;
try {
if (!(config.getProtocol() instanceof FederationProtocol)) {
LOG.error("Unsupported protocol");
throw new IllegalStateException("Unsupported protocol");
}
String issuerURL = resolveIssuer(request, config);
LOG.debug("Issuer url: {}", issuerURL);
if (issuerURL != null && issuerURL.length() > 0) {
redirectURL = issuerURL;
}
String wAuth = resolveAuthenticationType(request, config);
LOG.debug("WAuth: {}", wAuth);
String wReq = resolveRequest(request, config);
LOG.debug("WReq: {}", wReq);
String homeRealm = resolveHomeRealm(request, config);
LOG.debug("HomeRealm: {}", homeRealm);
String freshness = resolveFreshness(request, config);
LOG.debug("Freshness: {}", freshness);
String signInQuery = resolveSignInQuery(request, config);
LOG.debug("SignIn Query: {}", signInQuery);
String wctx = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
StringBuffer requestURL = request.getRequestURL();
String params = request.getQueryString();
if (params != null && !params.isEmpty()) {
requestURL.append("?").append(params);
}
requestState = new RequestState();
requestState.setTargetAddress(requestURL.toString());
requestState.setIdpServiceAddress(redirectURL);
requestState.setState(wctx);
requestState.setCreatedAt(System.currentTimeMillis());
StringBuilder sb = new StringBuilder();
sb.append(FederationConstants.PARAM_ACTION).append('=').append(FederationConstants.ACTION_SIGNIN);
String reply = ((FederationProtocol)config.getProtocol()).getReply();
if (reply == null || reply.length() == 0) {
reply = request.getRequestURL().toString();
} else {
try {
new URL(reply);
} catch (MalformedURLException ex) {
if (reply.startsWith("/")) {
reply = extractFullContextPath(request).concat(reply.substring(1));
} else {
reply = extractFullContextPath(request).concat(reply);
}
}
}
LOG.debug("wreply={}", reply);
sb.append('&').append(FederationConstants.PARAM_REPLY).append('=');
sb.append(URLEncoder.encode(reply, "UTF-8"));
String realm = resolveWTRealm(request, config);
LOG.debug("wtrealm={}", realm);
// add wtrealm parameter
sb.append('&').append(FederationConstants.PARAM_TREALM).append('=').append(URLEncoder
.encode(realm, "UTF-8"));
// add authentication type parameter wauth if set
if (wAuth != null && wAuth.length() > 0) {
sb.append('&').append(FederationConstants.PARAM_AUTH_TYPE).append('=').append(URLEncoder
.encode(wAuth,
"UTF-8"));
}
// add tokenRequest parameter wreq if set
if (wReq != null && wReq.length() > 0) {
sb.append('&').append(FederationConstants.PARAM_REQUEST).append('=').append(URLEncoder.encode(wReq,
"UTF-8"));
}
// add home realm parameter whr if set
if (homeRealm != null && homeRealm.length() > 0) {
sb.append('&').append(FederationConstants.PARAM_HOME_REALM).append('=').append(URLEncoder
.encode(homeRealm,
"UTF-8"));
}
// add freshness parameter wfresh if set
if (freshness != null && freshness.length() > 0) {
sb.append('&').append(FederationConstants.PARAM_FRESHNESS).append('=').append(URLEncoder
.encode(freshness,
"UTF-8"));
}
// add current time parameter wct
Date creationTime = new Date();
XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
String wct = fmt.format(creationTime);
sb.append('&').append(FederationConstants.PARAM_CURRENT_TIME).append('=')
.append(URLEncoder.encode(wct, "UTF-8"));
LOG.debug("wctx={}", wctx);
sb.append('&').append(FederationConstants.PARAM_CONTEXT).append('=');
sb.append(URLEncoder.encode(wctx, "UTF-8"));
// add signin query extensions
if (signInQuery != null && signInQuery.length() > 0) {
sb.append('&').append(signInQuery);
}
redirectURL = redirectURL + "?" + sb.toString();
} catch (Exception ex) {
LOG.error("Failed to create SignInRequest", ex);
throw new ProcessingException("Failed to create SignInRequest");
}
RedirectionResponse response = new RedirectionResponse();
response.setRedirectionURL(redirectURL);
response.setRequestState(requestState);
return response;
}
@Override
public RedirectionResponse createSignOutRequest(HttpServletRequest request, SamlAssertionWrapper token,
FedizContext config) throws ProcessingException {
String redirectURL = null;
try {
if (!(config.getProtocol() instanceof FederationProtocol)) {
LOG.error("Unsupported protocol");
throw new IllegalStateException("Unsupported protocol");
}
String issuerURL = resolveIssuer(request, config);
LOG.debug("Issuer url: {}", issuerURL);
if (issuerURL != null && issuerURL.length() > 0) {
redirectURL = issuerURL;
}
StringBuilder sb = new StringBuilder();
sb.append(FederationConstants.PARAM_ACTION).append('=').append(FederationConstants.ACTION_SIGNOUT);
String logoutRedirectTo = request.getParameter(FederationConstants.PARAM_REPLY);
if (logoutRedirectTo != null && !logoutRedirectTo.isEmpty()) {
logoutRedirectTo = config.getLogoutRedirectTo();
}
if (logoutRedirectTo != null && !logoutRedirectTo.isEmpty()) {
if (logoutRedirectTo.startsWith("/")) {
logoutRedirectTo = extractFullContextPath(request).concat(logoutRedirectTo.substring(1));
} else {
logoutRedirectTo = extractFullContextPath(request).concat(logoutRedirectTo);
}
LOG.debug("wreply={}", logoutRedirectTo);
sb.append('&').append(FederationConstants.PARAM_REPLY).append('=');
sb.append(URLEncoder.encode(logoutRedirectTo, "UTF-8"));
}
redirectURL = redirectURL + "?" + sb.toString();
} catch (Exception ex) {
LOG.error("Failed to create SignInRequest", ex);
throw new ProcessingException("Failed to create SignInRequest");
}
RedirectionResponse response = new RedirectionResponse();
response.setRedirectionURL(redirectURL);
return response;
}
private String resolveSignInQuery(HttpServletRequest request, FedizContext config) throws IOException,
UnsupportedCallbackException, UnsupportedEncodingException {
Object signInQueryObj = ((FederationProtocol)config.getProtocol()).getSignInQuery();
String signInQuery = null;
if (signInQueryObj != null) {
if (signInQueryObj instanceof String) {
signInQuery = (String)signInQueryObj;
} else if (signInQueryObj instanceof CallbackHandler) {
CallbackHandler frCB = (CallbackHandler)signInQueryObj;
SignInQueryCallback callback = new SignInQueryCallback(request);
frCB.handle(new Callback[] {
callback
});
Map<String, String> signInQueryMap = callback.getSignInQueryParamMap();
StringBuilder sbQuery = new StringBuilder();
for (String key : signInQueryMap.keySet()) {
if (sbQuery.length() > 0) {
sbQuery.append("&");
}
sbQuery.append(key).append('=').append(URLEncoder.encode(signInQueryMap.get(key), "UTF-8"));
}
signInQuery = sbQuery.toString();
}
}
return signInQuery;
}
private String resolveFreshness(HttpServletRequest request, FedizContext config) throws IOException,
UnsupportedCallbackException {
Object freshnessObj = ((FederationProtocol)config.getProtocol()).getFreshness();
String freshness = null;
if (freshnessObj != null) {
if (freshnessObj instanceof String) {
freshness = (String)freshnessObj;
} else if (freshnessObj instanceof CallbackHandler) {
CallbackHandler frCB = (CallbackHandler)freshnessObj;
FreshnessCallback callback = new FreshnessCallback(request);
frCB.handle(new Callback[] {
callback
});
freshness = callback.getFreshness();
}
}
return freshness;
}
private String resolveHomeRealm(HttpServletRequest request, FedizContext config) {
// Check if whr parameter was provided in request
String homeRealm = request.getParameter(FederationConstants.PARAM_HOME_REALM);
if (homeRealm != null && !homeRealm.isEmpty()) {
LOG.debug("HomeRealm was defined as 'whr' request parameter and will be used for IDP redirect");
} else {
// Check if home realm is set in configuration
Object homeRealmObj = ((FederationProtocol)config.getProtocol()).getHomeRealm();
if (homeRealmObj != null) {
if (homeRealmObj instanceof String) {
homeRealm = (String)homeRealmObj;
} else if (homeRealmObj instanceof CallbackHandler) {
homeRealm = resolveHomeRealm(homeRealmObj, request);
} else if (homeRealmObj instanceof List<?>) {
for (Object cbh : (List<?>)homeRealmObj) {
homeRealm = resolveHomeRealm(cbh, request);
if (homeRealm != null) {
LOG.debug("Home realm was found by {}", cbh.getClass());
break;
}
}
}
}
}
LOG.debug("Users home realm will be set to {}", homeRealm);
return homeRealm;
}
private String resolveHomeRealm(Object cbh, HttpServletRequest request) {
if (cbh instanceof CallbackHandler) {
CallbackHandler hrCBH = (CallbackHandler)cbh;
HomeRealmCallback callback = new HomeRealmCallback(request);
try {
hrCBH.handle(new Callback[] {callback});
} catch (IOException | UnsupportedCallbackException e) {
LOG.warn("Home Realm Callbackhandler caused an exception", e);
}
return callback.getHomeRealm();
} else {
LOG.warn("Callback Handler was not an instanceof CallbackHandler: {}", cbh);
return null;
}
}
private String resolveAuthenticationType(HttpServletRequest request, FedizContext config) throws IOException,
UnsupportedCallbackException {
Object wAuthObj = ((FederationProtocol)config.getProtocol()).getAuthenticationType();
String wAuth = null;
if (wAuthObj != null) {
if (wAuthObj instanceof String) {
wAuth = (String)wAuthObj;
} else if (wAuthObj instanceof CallbackHandler) {
CallbackHandler wauthCB = (CallbackHandler)wAuthObj;
WAuthCallback callback = new WAuthCallback(request);
wauthCB.handle(new Callback[] {
callback
});
wAuth = callback.getWauth();
}
}
return wAuth;
}
private String resolveRequest(HttpServletRequest request, FedizContext config) throws IOException,
UnsupportedCallbackException {
Object wReqObj = ((FederationProtocol)config.getProtocol()).getRequest();
String wReq = null;
if (wReqObj != null) {
if (wReqObj instanceof String) {
wReq = (String)wReqObj;
} else if (wReqObj instanceof CallbackHandler) {
CallbackHandler wauthCB = (CallbackHandler)wReqObj;
WReqCallback callback = new WReqCallback(request);
wauthCB.handle(new Callback[] {
callback
});
wReq = callback.getWreq();
}
}
return wReq;
}
private void testForMandatoryClaims(String roleURI,
List<org.apache.cxf.fediz.core.config.Claim> requestedClaims,
List<org.apache.cxf.fediz.core.Claim> receivedClaims,
boolean foundRoles
) throws ProcessingException {
if (requestedClaims != null) {
for (org.apache.cxf.fediz.core.config.Claim requestedClaim : requestedClaims) {
if (!requestedClaim.isOptional()) {
boolean found = false;
for (org.apache.cxf.fediz.core.Claim receivedClaim : receivedClaims) {
if (requestedClaim.getType().equals(receivedClaim.getClaimType().toString())) {
found = true;
break;
}
}
if (!found && foundRoles && roleURI != null && roleURI.equals(requestedClaim.getType())) {
// Maybe the requested claim is a role, which has already been removed
// from the claims collection
found = true;
}
if (!found) {
LOG.warn("Mandatory claim {} not found in token", requestedClaim.getType());
throw new ProcessingException("Mandatory claim not found in token", TYPE.INVALID_REQUEST);
}
}
}
}
}
private static class DecryptionCallbackHandler implements CallbackHandler {
private final String password;
DecryptionCallbackHandler(String password) {
this.password = password;
}
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof WSPasswordCallback) {
WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
pc.setPassword(password);
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}
private static class NOOpProcessor implements Processor {
@Override
public List<WSSecurityEngineResult> handleToken(Element arg0, RequestData arg1, WSDocInfo arg2)
throws WSSecurityException {
return Collections.emptyList();
}
}
}