Author: jim.ma
Date: 2013-10-22 04:14:11 -0400 (Tue, 22 Oct 2013)
New Revision: 18032
Added:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthConfig.java
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthContext.java
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/module/SOAPClientAuthModule.java
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/wss/interceptor/
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/wss/interceptor/WSS4JOutInterceptor.java
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/JASPISoapClientTest.java
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/UsernamePasswordCallbackHandler.java
projects/jaspic-soap/trunk/src/test/resources/jaspi-config-client.xml
projects/jaspic-soap/trunk/src/test/resources/plain-soapmessage.xml
Modified:
projects/jaspic-soap/trunk/pom.xml
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSAuthConfigProvider.java
Log:
Add client api implementation and test
Modified: projects/jaspic-soap/trunk/pom.xml
===================================================================
--- projects/jaspic-soap/trunk/pom.xml 2013-10-22 06:37:29 UTC (rev 18031)
+++ projects/jaspic-soap/trunk/pom.xml 2013-10-22 08:14:11 UTC (rev 18032)
@@ -29,7 +29,7 @@
<log4j.version>1.2.16</log4j.version>
<opensaml.version>2.5.3</opensaml.version>
<saaj.api.version>1.0.1.Final</saaj.api.version>
- <wss4j.version>1.6.12</wss4j.version>
+ <wss4j.version>2.0-SNAPSHOT</wss4j.version>
<jboss-logging.version>3.1.2.GA</jboss-logging.version>
</properties>
@@ -55,24 +55,43 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.wss4j</groupId>
+ <artifactId>wss4j-ws-security-dom</artifactId>
+ <version>${wss4j.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wss4j</groupId>
+ <artifactId>wss4j-policy</artifactId>
+ <version>${wss4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wss4j</groupId>
+ <artifactId>wss4j-ws-security-common</artifactId>
+ <version>${wss4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wss4j</groupId>
+ <artifactId>wss4j-ws-security-stax</artifactId>
+ <version>${wss4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wss4j</groupId>
+ <artifactId>wss4j-ws-security-policy-stax</artifactId>
+ <version>${wss4j.version}</version>
+ </dependency>
- <dependency>
- <groupId>org.apache.ws.security</groupId>
- <artifactId>wss4j</artifactId>
- <version>${wss4j.version}</version>
- <exclusions>
- <exclusion>
- <groupId>xerces</groupId>
- <artifactId>xercesImpl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
<dependency>
<groupId>org.picketbox</groupId>
<artifactId>jbosssx-bare</artifactId>
Modified:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSAuthConfigProvider.java
===================================================================
---
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSAuthConfigProvider.java 2013-10-22
06:37:29 UTC (rev 18031)
+++
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSAuthConfigProvider.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -45,9 +45,9 @@
}
@Override
- public ClientAuthConfig getClientAuthConfig(String layer,String appContext,
CallbackHandler handler) throws AuthException, SecurityException {
- //TODO:implement it
- return null;
+ public ClientAuthConfig getClientAuthConfig(String layer,
+ String appContext, CallbackHandler handler) throws AuthException, SecurityException {
+ return new JBossWSClientAuthConfig(layer, appContext, handler, contextProperties);
}
@Override
Added:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthConfig.java
===================================================================
---
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthConfig.java
(rev 0)
+++
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthConfig.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,146 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.jaspic.container.config;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.message.AuthException;
+import javax.security.auth.message.config.ClientAuthContext;
+import javax.security.auth.message.module.ClientAuthModule;
+
+import org.jboss.security.PicketBoxMessages;
+import org.jboss.security.SecurityConstants;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.auth.container.config.AuthModuleEntry;
+import org.jboss.security.auth.login.AuthenticationInfo;
+import org.jboss.security.auth.login.BaseAuthenticationInfo;
+import org.jboss.security.auth.login.JASPIAuthenticationInfo;
+import org.jboss.security.auth.message.config.JBossClientAuthConfig;
+import org.jboss.security.config.ApplicationPolicy;
+import org.jboss.security.config.ControlFlag;
+import org.jboss.security.config.SecurityConfiguration;
+import org.jboss.security.plugins.ClassLoaderLocator;
+import org.jboss.security.plugins.ClassLoaderLocatorFactory;
+
+/**
+ * @author <a href="ema(a)redhat.com">Jim Ma</a>
+ */
+public class JBossWSClientAuthConfig extends JBossClientAuthConfig {
+
+ @SuppressWarnings("rawtypes")
+ private List modules = new ArrayList();
+ private CallbackHandler callbackHandler;
+
+ @SuppressWarnings("rawtypes")
+ public JBossWSClientAuthConfig(String layer, String appContext,
+ CallbackHandler handler, Map properties) {
+ super(layer, appContext, handler, properties);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public ClientAuthContext getAuthContext(String authContextID,
+ Subject clientSubject, Map properties) throws AuthException {
+ List<ControlFlag> controlFlags = new ArrayList<ControlFlag>();
+
+ Map<String, Map> mapOptionsByName = new HashMap<String, Map>();
+ SecurityContext securityContext = SecurityActions.getSecurityContext();
+ String secDomain = null;
+ if (securityContext != null) {
+ secDomain = securityContext.getSecurityDomain();
+ } else {
+ secDomain = (String) properties.get("security-domain");
+ if (secDomain == null)
+ throw PicketBoxMessages.MESSAGES
+ .failedToObtainSecDomainFromContextOrConfig();
+ }
+
+ String defaultAppDomain = SecurityConstants.DEFAULT_APPLICATION_POLICY;
+ // Get the modules from the SecurityConfiguration
+ ApplicationPolicy ap = SecurityConfiguration
+ .getApplicationPolicy(secDomain);
+ if (ap == null) {
+ ap = SecurityConfiguration.getApplicationPolicy(defaultAppDomain);
+ }
+ if (ap == null)
+ throw PicketBoxMessages.MESSAGES
+ .failedToObtainApplicationPolicy(secDomain);
+ BaseAuthenticationInfo bai = ap.getAuthenticationInfo();
+ if (bai == null)
+ throw PicketBoxMessages.MESSAGES
+ .failedToObtainAuthenticationInfo(secDomain);
+
+ if (bai instanceof AuthenticationInfo) {
+ throw new AuthException("Unexpected authentication configuration");
+
+ } else {
+ JASPIAuthenticationInfo jai = (JASPIAuthenticationInfo) bai;
+ AuthModuleEntry[] amearr = jai.getAuthModuleEntry();
+
+ ClassLoader moduleCL = null;
+ String jbossModule = jai.getJBossModuleName();
+ if (jbossModule != null && !jbossModule.isEmpty()) {
+ ClassLoaderLocator locator = ClassLoaderLocatorFactory.get();
+ if (locator != null)
+ moduleCL = locator.get(jbossModule);
+ }
+
+ for (AuthModuleEntry ame : amearr) {
+
+ try {
+ mapOptionsByName.put(ame.getAuthModuleName(),
+ ame.getOptions());
+ controlFlags.add(ame.getControlFlag());
+ ClientAuthModule sam = this.createCAM(moduleCL,
+ ame.getAuthModuleName());
+
+ Map options = new HashMap();
+ sam.initialize(null, null, callbackHandler, options);
+ modules.add(sam);
+ } catch (Exception e) {
+ throw new AuthException(e.getLocalizedMessage());
+ }
+ }
+
+ }
+ return new JBossWSClientAuthContext(this);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private ClientAuthModule createCAM(ClassLoader moduleCL, String name)
+ throws Exception {
+ Class clazz = SecurityActions.loadClass(moduleCL, name);
+ Constructor ctr = clazz.getConstructor(new Class[0]);
+ return (ClientAuthModule) ctr.newInstance(new Object[0]);
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ public List getClientAuthModules() {
+ return modules;
+ }
+
+}
\ No newline at end of file
Property changes on:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthConfig.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthContext.java
===================================================================
---
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthContext.java
(rev 0)
+++
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthContext.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.jaspic.container.config;
+
+import org.jboss.security.auth.message.config.JBossClientAuthContext;
+
+/**
+ * @author <a href="ema(a)redhat.com">Jim Ma</a>
+ */
+// TODO:refactor JBossClientAuthContex
+public class JBossWSClientAuthContext extends JBossClientAuthContext {
+
+
+ public JBossWSClientAuthContext(JBossWSClientAuthConfig config) {
+ super(config);
+ }
+}
\ No newline at end of file
Property changes on:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/config/JBossWSClientAuthContext.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/module/SOAPClientAuthModule.java
===================================================================
---
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/module/SOAPClientAuthModule.java
(rev 0)
+++
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/module/SOAPClientAuthModule.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.jaspic.container.module;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.message.AuthException;
+import javax.security.auth.message.AuthStatus;
+import javax.security.auth.message.MessageInfo;
+import javax.security.auth.message.MessagePolicy;
+import javax.security.auth.message.module.ClientAuthModule;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.SoapVersion;
+import org.apache.cxf.binding.soap.SoapVersionFactory;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.ws.security.WSSConfig;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.ws.jaspic.wss.interceptor.WSS4JOutInterceptor;
+/**
+ * @author <a href="ema(a)redhat.com">Jim Ma</a>
+ */
+public class SOAPClientAuthModule implements ClientAuthModule {
+
+ @SuppressWarnings("rawtypes")
+ private List<Class> supportedTypes = new ArrayList<Class>();
+ private SimplePrincipal principal = null;
+ private Object credential = null;
+
+ @SuppressWarnings("unused")
+ private MessagePolicy requestPolicy = null;
+ @SuppressWarnings("unused")
+ private MessagePolicy responsePolicy = null;
+ @SuppressWarnings("unused")
+ private CallbackHandler handler = null;
+ @SuppressWarnings({ "unused", "rawtypes" })
+ private Map options = null;
+
+ public SOAPClientAuthModule() {
+ this.supportedTypes.add(Object.class);
+ this.supportedTypes.add(SOAPMessage.class);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public SOAPClientAuthModule(List<Class> supportedTypes) {
+ this.supportedTypes = supportedTypes;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void initialize(MessagePolicy requestPolicy,
+ MessagePolicy responsePolicy, CallbackHandler handler, Map options)
+ throws AuthException {
+ this.requestPolicy = requestPolicy;
+ this.responsePolicy = responsePolicy;
+ this.handler = handler;
+ this.options = options;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public AuthStatus secureRequest(MessageInfo messageInfo, Subject source)
+ throws AuthException {
+
+ SOAPMessage soapMessage = (SOAPMessage) messageInfo.getRequestMessage();
+ SoapVersion soapVersion = null;
+ try {
+ String ns = soapMessage.getSOAPBody().getNamespaceURI();
+ soapVersion = SoapVersionFactory.getInstance().getSoapVersion(ns);
+ } catch (SOAPException e) {
+ throw new AuthException(e.getMessage());
+ }
+ if (soapVersion == null) {
+ throw new AuthException("Invalid soap message");
+ }
+
+ Exchange exchange = new ExchangeImpl();
+ MessageImpl messageImpl = new MessageImpl();
+ messageImpl.setExchange(exchange);
+ SoapMessage cxfSoapMessage = new SoapMessage(messageImpl);
+ cxfSoapMessage.setVersion(soapVersion);
+ cxfSoapMessage.setContent(SOAPMessage.class, soapMessage);
+
+ WSSConfig wssConfig = WSSConfig.getNewInstance();
+ cxfSoapMessage.put(WSSConfig.class.getName(), wssConfig);
+
+ Map map = messageInfo.getMap();
+ WSS4JOutInterceptor wss4jOutInterceptor = new WSS4JOutInterceptor(map);
+ wss4jOutInterceptor.createEndingInterceptor().handleMessage(cxfSoapMessage);
+ return AuthStatus.SUCCESS;
+ }
+
+ public AuthStatus validateResponse(MessageInfo messageInfo, Subject source,
+ Subject recipient) throws AuthException {
+ // TODO:to implement
+ return AuthStatus.SUCCESS;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Class[] getSupportedMessageTypes() {
+ Class[] clsarr = new Class[this.supportedTypes.size()];
+ supportedTypes.toArray(clsarr);
+ return clsarr;
+ }
+
+ public void cleanSubject(MessageInfo messageInfo, Subject subject)
+ throws AuthException {
+ subject.getPrincipals().remove(principal);
+ subject.getPublicCredentials().remove(credential);
+ }
+
+}
Property changes on:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/container/module/SOAPClientAuthModule.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/wss/interceptor/WSS4JOutInterceptor.java
===================================================================
---
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/wss/interceptor/WSS4JOutInterceptor.java
(rev 0)
+++
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/wss/interceptor/WSS4JOutInterceptor.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,360 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.jaspic.wss.interceptor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.soap.SOAPMessage;
+
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.SoapVersion;
+import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptor;
+import org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.action.Action;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+/**
+ * This is a copy of WSS4JOutInterceptor and public WSS4JOutInterceptorInternal
+ * We need to refactor the WSS4JOutInterceptor and directly use it
+ * @author <a href="ema(a)redhat.com">Jim Ma</a>
+ *
+ */
+public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
+
+ /**
+ * Property name for a map of action IDs ({@link Integer}) to action
+ * class names. Values can be either {@link Class}) or Objects
+- * implementing {@link Action}.
+ */
+ public static final String WSS4J_ACTION_MAP = "wss4j.action.map";
+
+ private static final Logger LOG = LogUtils
+ .getL7dLogger(WSS4JOutInterceptor.class);
+
+ private static final Logger TIME_LOG = LogUtils
+ .getL7dLogger(WSS4JOutInterceptor.class,
+ null,
+ WSS4JOutInterceptor.class.getName() + "-Time");
+
+ private WSS4JOutInterceptorInternal ending;
+ private SAAJOutInterceptor saajOut = new SAAJOutInterceptor();
+ private boolean mtomEnabled;
+
+
+
+ public WSS4JOutInterceptor() {
+ super();
+ setPhase(Phase.PRE_PROTOCOL);
+ getAfter().add(SAAJOutInterceptor.class.getName());
+
+ ending = createEndingInterceptor();
+ }
+
+ public WSS4JOutInterceptor(Map<String, Object> props) {
+ this();
+ setProperties(props);
+ }
+
+ public boolean isAllowMTOM() {
+ return mtomEnabled;
+ }
+ /**
+ * Enable or disable mtom with WS-Security. By default MTOM is disabled as
+ * attachments would not get encrypted or be part of the signature.
+ * @param mtomEnabled
+ */
+ public void setAllowMTOM(boolean allowMTOM) {
+ this.mtomEnabled = allowMTOM;
+ }
+
+
+ @Override
+ public Object getProperty(Object msgContext, String key) {
+ // use the superclass first
+ Object result = super.getProperty(msgContext, key);
+
+ // handle the special case of the RECV_RESULTS
+ if (result == null
+ && WSHandlerConstants.RECV_RESULTS.equals(key)
+ && !this.isRequestor((SoapMessage)msgContext)) {
+ result = ((SoapMessage)msgContext).getExchange().getInMessage().get(key);
+ }
+ return result;
+ }
+
+ public void handleMessage(SoapMessage mc) throws Fault {
+ //must turn off mtom when using WS-Sec so binary is inlined so it can
+ //be properly signed/encrypted/etc...
+ if (!mtomEnabled) {
+ mc.put(org.apache.cxf.message.Message.MTOM_ENABLED, false);
+ }
+
+ if (mc.getContent(SOAPMessage.class) == null) {
+ saajOut.handleMessage(mc);
+ }
+
+ mc.getInterceptorChain().add(ending);
+ }
+ public void handleFault(SoapMessage message) {
+ saajOut.handleFault(message);
+ }
+
+ public final WSS4JOutInterceptorInternal createEndingInterceptor() {
+ return new WSS4JOutInterceptorInternal();
+ }
+
+ public class WSS4JOutInterceptorInternal
+ implements PhaseInterceptor<SoapMessage> {
+ public WSS4JOutInterceptorInternal() {
+ super();
+ }
+
+ public void handleMessage(SoapMessage mc) throws Fault {
+
+ boolean doDebug = LOG.isLoggable(Level.FINE);
+ boolean doTimeDebug = TIME_LOG.isLoggable(Level.FINE);
+
+ long t0 = 0;
+ long t1 = 0;
+ long t2 = 0;
+
+ if (doTimeDebug) {
+ t0 = System.currentTimeMillis();
+ }
+
+ if (doDebug) {
+ LOG.fine("WSS4JOutInterceptor: enter handleMessage()");
+ }
+ /**
+ * There is nothing to send...Usually happens when the provider
+ * needs to send a HTTP 202 message (with no content)
+ */
+ if (mc == null) {
+ return;
+ }
+ SoapVersion version = mc.getVersion();
+ RequestData reqData = new RequestData();
+ translateProperties(mc);
+
+ reqData.setMsgContext(mc);
+
+ /*
+ * The overall try, just to have a finally at the end to perform some
+ * housekeeping.
+ */
+ try {
+ WSSConfig config = WSSConfig.getNewInstance();
+ reqData.setWssConfig(config);
+
+ /*
+ * Setup any custom actions first by processing the input properties
+ * and reconfiguring the WSSConfig with the user defined properties.
+ */
+ this.configureActions(mc, doDebug, version, config);
+
+ /*
+ * Get the action first.
+ */
+ List<Integer> actions = new ArrayList<Integer>();
+ String action = getString(WSHandlerConstants.ACTION, mc);
+ if (action == null) {
+ throw new SoapFault(new Message("NO_ACTION", LOG), version
+ .getReceiver());
+ }
+
+ int doAction = WSSecurityUtil.decodeAction(action, actions, config);
+ if (doAction == WSConstants.NO_SECURITY && actions.isEmpty()) {
+ return;
+ }
+
+ /*
+ * For every action we need a username, so get this now. The
+ * username defined in the deployment descriptor takes precedence.
+ */
+ reqData.setUsername((String) getOption(WSHandlerConstants.USER));
+ if (reqData.getUsername() == null
+ || reqData.getUsername().equals("")) {
+ String username = (String) getProperty(reqData.getMsgContext(),
+ WSHandlerConstants.USER);
+ if (username != null) {
+ reqData.setUsername(username);
+ }
+ }
+
+ /*
+ * Now we perform some set-up for UsernameToken and Signature
+ * functions. No need to do it for encryption only. Check if
+ * username is available and then get a passowrd.
+ */
+ if ((doAction & (WSConstants.SIGN | WSConstants.UT |
WSConstants.UT_SIGN)) != 0
+ && (reqData.getUsername() == null
+ || reqData.getUsername().equals(""))) {
+ /*
+ * We need a username - if none throw an SoapFault. For
+ * encryption there is a specific parameter to get a username.
+ */
+ throw new SoapFault(new Message("NO_USERNAME", LOG),
version
+ .getReceiver());
+ }
+ if (doDebug) {
+ LOG.fine("Action: " + doAction);
+ LOG.fine("Actor: " + reqData.getActor());
+ }
+ /*
+ * Now get the SOAP part from the request message and convert it
+ * into a Document. This forces CXF to serialize the SOAP request
+ * into FORM_STRING. This string is converted into a document.
+ * During the FORM_STRING serialization CXF performs multi-ref of
+ * complex data types (if requested), generates and inserts
+ * references for attachements and so on. The resulting Document
+ * MUST be the complete and final SOAP request as CXF would send it
+ * over the wire. Therefore this must shall be the last (or only)
+ * handler in a chain. Now we can perform our security operations on
+ * this request.
+ */
+
+ SOAPMessage saaj = mc.getContent(SOAPMessage.class);
+
+ if (saaj == null) {
+ LOG.warning("SAAJOutHandler must be enabled for
WS-Security!");
+ throw new SoapFault(new Message("NO_SAAJ_DOC", LOG),
version
+ .getReceiver());
+ }
+
+ Document doc = saaj.getSOAPPart();
+
+ if (doTimeDebug) {
+ t1 = System.currentTimeMillis();
+ }
+
+ doSenderAction(doAction, doc, reqData, actions, Boolean.TRUE
+ .equals(getProperty(mc,
org.apache.cxf.message.Message.REQUESTOR_ROLE)));
+
+ if (doTimeDebug) {
+ t2 = System.currentTimeMillis();
+ TIME_LOG.fine("Send request: total= " + (t2 - t0)
+ + " request preparation= " + (t1 - t0)
+ + " request processing= " + (t2 - t1)
+ + "\n");
+ }
+
+ if (doDebug) {
+ LOG.fine("WSS4JOutInterceptor: exit handleMessage()");
+ }
+ } catch (WSSecurityException e) {
+ throw new SoapFault(new Message("SECURITY_FAILED", LOG), e,
version
+ .getSender());
+ } finally {
+ reqData.clear();
+ reqData = null;
+ }
+ }
+
+ public Set<String> getAfter() {
+ return Collections.emptySet();
+ }
+
+ public Set<String> getBefore() {
+ return Collections.emptySet();
+ }
+
+ public String getId() {
+ return WSS4JOutInterceptorInternal.class.getName();
+ }
+
+ public String getPhase() {
+ return Phase.POST_PROTOCOL;
+ }
+
+ public void handleFault(SoapMessage message) {
+ //nothing
+ }
+
+ private void configureActions(SoapMessage mc, boolean doDebug,
+ SoapVersion version, WSSConfig config) {
+
+ final Map<Integer, Object> actionMap = CastUtils.cast(
+ (Map<?, ?>)getProperty(mc, WSS4J_ACTION_MAP));
+ if (actionMap != null) {
+ for (Map.Entry<Integer, Object> entry : actionMap.entrySet()) {
+ Class<?> removedAction = null;
+
+ // Be defensive here since the cast above is slightly risky
+ // with the handler config options not being strongly typed.
+ try {
+ if (entry.getValue() instanceof Class<?>) {
+ removedAction = config.setAction(
+ entry.getKey().intValue(),
+ (Class<?>)entry.getValue());
+ } else if (entry.getValue() instanceof Action) {
+ removedAction = config.setAction(
+ entry.getKey().intValue(),
+ (Action)entry.getValue());
+ } else {
+ throw new SoapFault(new Message("BAD_ACTION", LOG),
version
+ .getReceiver());
+ }
+ } catch (ClassCastException e) {
+ throw new SoapFault(new Message("BAD_ACTION", LOG),
version
+ .getReceiver());
+ }
+
+ if (doDebug) {
+ if (removedAction != null) {
+ LOG.fine("Replaced Action: " +
removedAction.getName()
+ + " with Action: " + entry.getValue()
+ + " for ID: " + entry.getKey());
+ } else {
+ LOG.fine("Added Action: " + entry.getValue()
+ + " with ID: " + entry.getKey());
+ }
+ }
+ }
+ }
+ }
+
+ public Collection<PhaseInterceptor<? extends
org.apache.cxf.message.Message>>
+ getAdditionalInterceptors() {
+ return null;
+ }
+ }
+}
Property changes on:
projects/jaspic-soap/trunk/src/main/java/org/jboss/ws/jaspic/wss/interceptor/WSS4JOutInterceptor.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added:
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/JASPISoapClientTest.java
===================================================================
---
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/JASPISoapClientTest.java
(rev 0)
+++
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/JASPISoapClientTest.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.jaspic.container.config;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Properties;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.message.AuthStatus;
+import javax.security.auth.message.MessageInfo;
+import javax.security.auth.message.config.AuthConfigFactory;
+import javax.security.auth.message.config.AuthConfigProvider;
+import javax.security.auth.message.config.ClientAuthConfig;
+import javax.security.auth.message.config.ClientAuthContext;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+
+import junit.framework.TestCase;
+
+import org.jboss.security.auth.callback.JBossCallbackHandler;
+import org.jboss.security.auth.login.XMLLoginConfigImpl;
+import org.jboss.security.auth.message.GenericMessageInfo;
+import org.junit.BeforeClass;
+import org.junit.Test;
+/**
+ * @author <a href="ema(a)redhat.com">Jim Ma</a>
+ */
+public class JASPISoapClientTest extends TestCase {
+
+ @BeforeClass
+ protected void setUp() throws Exception {
+ XMLLoginConfigImpl xli = XMLLoginConfigImpl.getInstance();
+
+ setJAASConfiguration(xli);
+
+ URL configURL = Thread.currentThread().getContextClassLoader()
+ .getResource("jaspi-config-client.xml");
+ assertNotNull("Config URL", configURL);
+
+ xli.setConfigURL(configURL);
+ xli.loadConfig();
+ }
+
+ @Test
+ @SuppressWarnings({ "unchecked"})
+ public void testValidateUTPlainPassword() throws Exception {
+ AuthConfigFactory factory = AuthConfigFactory.getFactory();
+ Properties properties = new Properties();
+ String appId = "localhost /jbossws-spi/endpointB";
+ String layer = "SOAP";
+ AuthConfigProvider provider = new JBossWSAuthConfigProvider(properties, factory);
+ provider = factory.getConfigProvider(layer, appId, null);
+
+ JBossCallbackHandler callbackHandler = new JBossCallbackHandler();
+ ClientAuthConfig clientConfig = provider.getClientAuthConfig(layer,
+ appId, callbackHandler);
+
+ Properties serverContextProperties = new Properties();
+ serverContextProperties.setProperty("security-domain",
"client-jaspi");
+ ClientAuthContext sctx = clientConfig.getAuthContext("helloWorld", new
Subject(), serverContextProperties);
+
+ MessageInfo messageInfo = new GenericMessageInfo();
+
+ messageInfo.setRequestMessage(prepareSOAPMessage("plain-soapmessage.xml"));
+ Subject clientSubject = new Subject();
+ messageInfo.getMap().put("action", "UsernameToken");
+ messageInfo.getMap().put("passwordCallbackClass",
"org.jboss.ws.jaspic.container.config.UsernamePasswordCallbackHandler");
+ messageInfo.getMap().put("user", "Alice");
+ AuthStatus authStatus = sctx.secureRequest(messageInfo, clientSubject);
+ assertTrue(authStatus.equals(AuthStatus.SUCCESS));
+ SOAPMessage soapmessage = (SOAPMessage)messageInfo.getRequestMessage();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ soapmessage.writeTo(bout);
+ String out = new String(bout.toByteArray());
+ assertTrue(out.indexOf("wsse:UsernameToken") > -1);
+ assertTrue(out.indexOf("<wsse:Username>Alice</wsse:Username><wsse:Password")
> -1);
+
+ }
+
+ private static void setJAASConfiguration(final Configuration configuration) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ Configuration.setConfiguration(configuration);
+ return null;
+ }
+ });
+ }
+
+ private SOAPMessage prepareSOAPMessage(String messageFile) throws Exception {
+ MessageFactory factory = MessageFactory.newInstance();
+ URL fileURl = Thread.currentThread().getContextClassLoader()
+ .getResource(messageFile);
+ FileInputStream fins = new FileInputStream(fileURl.getFile());
+ return factory.createMessage(null, fins);
+ }
+}
+
Property changes on:
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/JASPISoapClientTest.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added:
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/UsernamePasswordCallbackHandler.java
===================================================================
---
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/UsernamePasswordCallbackHandler.java
(rev 0)
+++
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/UsernamePasswordCallbackHandler.java 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2013, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.jaspic.container.config;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.apache.ws.security.WSPasswordCallback;
+public class UsernamePasswordCallbackHandler implements CallbackHandler {
+
+ private Map<String, String> users = new HashMap<String, String>();
+
+ public UsernamePasswordCallbackHandler() {
+ users.put("wernerd", "verySecret");
+ users.put("bob", "security");
+ users.put("Alice", "securityPassword");
+ }
+
+ 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(users.get(pc.getIdentifier()));
+ } else {
+ throw new UnsupportedCallbackException(callbacks[i],
+ "Unrecognized Callback");
+ }
+ }
+ }
+}
Property changes on:
projects/jaspic-soap/trunk/src/test/java/org/jboss/ws/jaspic/container/config/UsernamePasswordCallbackHandler.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added: projects/jaspic-soap/trunk/src/test/resources/jaspi-config-client.xml
===================================================================
--- projects/jaspic-soap/trunk/src/test/resources/jaspi-config-client.xml
(rev 0)
+++ projects/jaspic-soap/trunk/src/test/resources/jaspi-config-client.xml 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,11 @@
+<?xml version='1.0'?>
+
+<policy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:security-config:5.0"
+ xmlns="urn:jboss:security-config:5.0">
+ <application-policy name="client-jaspi">
+ <authentication-jaspi>
+ <auth-module
code="org.jboss.ws.jaspic.container.module.SOAPClientAuthModule"/>
+ </authentication-jaspi>
+ </application-policy>
+</policy>
\ No newline at end of file
Property changes on:
projects/jaspic-soap/trunk/src/test/resources/jaspi-config-client.xml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native
Added: projects/jaspic-soap/trunk/src/test/resources/plain-soapmessage.xml
===================================================================
--- projects/jaspic-soap/trunk/src/test/resources/plain-soapmessage.xml
(rev 0)
+++ projects/jaspic-soap/trunk/src/test/resources/plain-soapmessage.xml 2013-10-22
08:14:11 UTC (rev 18032)
@@ -0,0 +1,9 @@
+<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+ <SOAP-ENV:Header
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
+ </SOAP-ENV:Header>
+ <soap:Body>
+ <ns2:DoubleIt
xmlns:ns2="http://www.example.org/schema/DoubleIt">
+ <numberToDouble>25</numberToDouble>
+ </ns2:DoubleIt>
+ </soap:Body>
+</soap:Envelope>
\ No newline at end of file
Property changes on: projects/jaspic-soap/trunk/src/test/resources/plain-soapmessage.xml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:keywords
+ Rev Date
Added: svn:eol-style
+ native