Author: ningjiang Date: Thu May 27 03:05:56 2010 New Revision: 948659 URL: http://svn.apache.org/viewvc?rev=948659&view=rev Log: CAMEL-2757 Added integration test for this feature
Added: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/ camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java (with props) camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java (with props) camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java (with props) camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java (with props) camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/ camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml (with props) camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml (with props) Modified: camel/trunk/tests/camel-itest/pom.xml Modified: camel/trunk/tests/camel-itest/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/pom.xml?rev=948659&r1=948658&r2=948659&view=diff ============================================================================== --- camel/trunk/tests/camel-itest/pom.xml (original) +++ camel/trunk/tests/camel-itest/pom.xml Thu May 27 03:05:56 2010 @@ -54,6 +54,12 @@ </exclusions> </dependency> <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-ws-security</artifactId> + <version>${cxf-version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jetty</artifactId> <scope>test</scope> @@ -78,7 +84,11 @@ <artifactId>camel-rss</artifactId> <scope>test</scope> </dependency> - + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-spring-security</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-mail</artifactId> Added: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java?rev=948659&view=auto ============================================================================== --- camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java (added) +++ camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java Thu May 27 03:05:56 2010 @@ -0,0 +1,113 @@ +/** + * 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.camel.itest.security; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.soap.SOAPFaultException; + +import org.apache.camel.CamelContext; +import org.apache.cxf.endpoint.Client; +import org.apache.cxf.frontend.ClientProxy; +import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; +import org.apache.hello_world_soap_http.Greeter; +import org.apache.ws.security.WSConstants; +import org.apache.ws.security.handler.WSHandlerConstants; +import org.apache.ws.security.message.token.UsernameToken; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + + +...@contextconfiguration(locations = {"camel-context.xml"}) +public class GreeterClientTest extends AbstractJUnit4SpringContextTests { + private static final java.net.URL WSDL_LOC; + static { + java.net.URL tmp = null; + try { + tmp = GreeterClientTest.class.getClassLoader().getResource("wsdl/hello_world.wsdl"); + } catch (final Exception e) { + e.printStackTrace(); + } + WSDL_LOC = tmp; + } + private static final QName SERVICE_QNAME = + new QName("http://apache.org/hello_world_soap_http", "SOAPService"); + + private static final QName PORT_QNAME = + new QName("http://apache.org/hello_world_soap_http", "SoapOverHttp" + ); + + @Autowired + protected CamelContext camelContext; + + protected String sendMessageWithUsernameToken(String username, String password, String message) throws Exception { + final javax.xml.ws.Service svc = javax.xml.ws.Service.create(WSDL_LOC, SERVICE_QNAME); + final Greeter greeter = svc.getPort(PORT_QNAME, Greeter.class); + + Client client = ClientProxy.getClient(greeter); + Map<String, Object> props = new HashMap<String, Object>(); + props.put("action", "UsernameToken"); + props.put("user", username); + // Set the the password type to be plain text, + // so we can keep using the password to authenticate with spring security + props.put(UsernameToken.PASSWORD_TYPE, WSConstants.PW_TEXT); + WSS4JOutInterceptor wss4jOut = new WSS4JOutInterceptor(props); + + client.getOutInterceptors().add(wss4jOut); + ((BindingProvider)greeter).getRequestContext().put("password", password); + return greeter.greetMe(message); + } + + @Test + public void testServiceWithValidateUser() throws Exception { + String response = sendMessageWithUsernameToken("jim", "jimspassword", "CXF"); + assertEquals(" Hello CXF", response); + + try { + sendMessageWithUsernameToken("jim", "foo", "CXF"); + fail("should fail"); + } catch (Exception ex) { + assertTrue("Get a wrong type exception.", ex instanceof SOAPFaultException); + assertTrue("Get a wrong exception message", ex.getMessage().startsWith("The security token could not be authenticated or authorized;")); + assertTrue("Get a wrong exception message", ex.getMessage().endsWith("java.io.IOException: Wrong password!")); + } + + } + + @Test + public void testServiceWithNotAuthorizedUser() throws Exception { + try { + // this user doesn't have the right to access the processor + sendMessageWithUsernameToken("bob", "bobspassword", "CXF"); + fail("should fail"); + } catch (Exception ex) { + assertTrue("Get a wrong type exception.", ex instanceof SOAPFaultException); + assertTrue("Get a wrong exception message", ex.getMessage().startsWith("Cannot access the processor which has been protected.")); + assertTrue("Get a wrong exception message", ex.getMessage().endsWith("Caused by: [org.springframework.security.AccessDeniedException - Access is denied]")); + } + } + +} Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/GreeterClientTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java?rev=948659&view=auto ============================================================================== --- camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java (added) +++ camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java Thu May 27 03:05:56 2010 @@ -0,0 +1,71 @@ +/** + * 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.camel.itest.security; + +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.WSConstants; +import org.apache.ws.security.WSPasswordCallback; + + +public class KeystorePasswordCallback implements CallbackHandler { + + private Map<String, String> passwords = + new HashMap<String, String>(); + + public KeystorePasswordCallback() { + passwords.put("alice", "password"); + passwords.put("jim", "jimspassword"); + passwords.put("bob", "bobspassword"); + } + + /** + * It attempts to get the password from the private + * alias/passwords map. + */ + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + WSPasswordCallback pc = (WSPasswordCallback)callbacks[i]; + String pass = passwords.get(pc.getIdentifier()); + if (WSConstants.PASSWORD_DIGEST.equals(pc.getPasswordType())) { + if (pass != null) { + pc.setPassword(pass); + return; + } + } + if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType())) { + // As the PasswordType is PasswordDigest, we need to do the authentication in the call back + if (!pc.getPassword().equals(pass)) { + throw new IOException("Wrong password!"); + } + } + } + } + + /** + * Add an alias/password pair to the callback mechanism. + */ + public void setAliasPassword(String alias, String password) { + passwords.put(alias, password); + } +} Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/KeystorePasswordCallback.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java?rev=948659&view=auto ============================================================================== --- camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java (added) +++ camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java Thu May 27 03:05:56 2010 @@ -0,0 +1,43 @@ +/** + * 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.camel.itest.security; + +import java.security.Principal; +import java.security.cert.X509Certificate; + +import javax.security.auth.Subject; + +import org.apache.camel.component.spring.security.converter.DefaultAuthenticationConverter; +import org.apache.ws.security.WSUsernameTokenPrincipal; +import org.springframework.security.Authentication; +import org.springframework.security.providers.UsernamePasswordAuthenticationToken; + +public class MyAuthenticationConverter extends DefaultAuthenticationConverter { + + protected Authentication convertToAuthentication(Subject subject) { + Authentication answer = null; + for (Principal principal : subject.getPrincipals()) { + if (principal instanceof WSUsernameTokenPrincipal) { + WSUsernameTokenPrincipal ut = (WSUsernameTokenPrincipal) principal; + answer = new UsernamePasswordAuthenticationToken(ut.getName(), ut.getPassword()); + break; + } + } + return answer; + } + +} Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyAuthenticationConverter.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java?rev=948659&view=auto ============================================================================== --- camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java (added) +++ camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java Thu May 27 03:05:56 2010 @@ -0,0 +1,45 @@ +/** + * 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.camel.itest.security; + +import java.util.List; + +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.component.cxf.CxfConstants; + +public class MyProcessor implements Processor { + + public void process(Exchange exchange) throws Exception { + Message in = exchange.getIn(); + // Get the parameter list + List<?> parameter = in.getBody(List.class); + // Get the operation name + String operation = (String)in.getHeader(CxfConstants.OPERATION_NAME); + Object result = null; + if ("sayHi".equals(operation)) { + result = " Hello buddy!"; + } + if ("greetMe".equals(operation)) { + result = " Hello " + (String)parameter.get(0); + } + // Put the result back + exchange.getOut().setBody(result); + } + +} Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/security/MyProcessor.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml?rev=948659&view=auto ============================================================================== --- camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml (added) +++ camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml Thu May 27 03:05:56 2010 @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<beans + xmlns="http://www.springframework.org/schema/beans" + xmlns:cxf="http://camel.apache.org/schema/cxf" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + + xsi:schemaLocation="http://camel.apache.org/schema/cxf + http://camel.apache.org/schema/cxf/camel-cxf.xsd + http://camel.apache.org/schema/spring-security + http://camel.apache.org/schema/spring-security/camel-spring-security.xsd + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://cxf.apache.org/jaxws + http://cxf.apache.org/schemas/jaxws.xsd"> + + <!-- import the spring security configuration --> + <import resource="classpath:org/apache/camel/itest/security/commonSecurity.xml"/> + + <authorizationPolicy id="admin" access="ROLE_ADMIN" + authenticationConverter="myAuthenticationConverter" + authenticationManager="authenticationManager" + accessDecisionManager="accessDecisionManager" + xmlns="http://camel.apache.org/schema/spring-security"/> + + <bean id="myAuthenticationConverter" class="org.apache.camel.itest.security.MyAuthenticationConverter"/> + <bean id="myProcessor" class="org.apache.camel.itest.security.MyProcessor"/> + + <camelContext id="myCamelContext" xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="cxf:bean:UsernameTokenEndpoint"/> + <!-- The exchange should be authenticated with the role of ADMIN before it is send to mock:endpoint --> + <policy ref="admin"> + <process ref="myProcessor"/> + </policy> + </route> + </camelContext> + + <!-- + UsernameToken endpoint definition + This endpoint is configured to read the username and password tokens + and validate them using a password callback handler. + --> + <cxf:cxfEndpoint + id="UsernameTokenEndpoint" + wsdlURL="wsdl/hello_world.wsdl" + serviceClass="org.apache.hello_world_soap_http.Greeter" + endpointName="s:SoapOverHttp" + serviceName="s:SOAPService" + xmlns:s="http://apache.org/hello_world_soap_http" + address="http://localhost:9000/SoapContext/SoapPort" + > + <cxf:inInterceptors> + <ref bean="UsernameToken_Request"/> + <!-- bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/--> + </cxf:inInterceptors> + </cxf:cxfEndpoint> + + <!-- + WSS4JInInterceptor for UsernameTokenEndpoint above + --> + <bean + id="UsernameToken_Request" + class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" + > + <constructor-arg> + <map> + <entry key="action" value="UsernameToken"/> + <entry key="passwordType" value="PasswordText"/> + <entry key="passwordCallbackClass" value="org.apache.camel.itest.security.KeystorePasswordCallback"/> + </map> + </constructor-arg> + </bean> + +</beans> Propchange: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml ------------------------------------------------------------------------------ svn:keywords = Rev Date Propchange: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/camel-context.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml Added: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml?rev=948659&view=auto ============================================================================== --- camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml (added) +++ camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml Thu May 27 03:05:56 2010 @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<!-- START SNIPPET: example --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:spring-security="http://www.springframework.org/schema/security" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/security + http://www.springframework.org/schema/security/spring-security.xsd"> + + <spring-security:authentication-manager alias="authenticationManager"/> + + <bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased"> + <property name="allowIfAllAbstainDecisions" value="true"/> + <property name="decisionVoters"> + <list> + <bean class="org.springframework.security.vote.RoleVoter"/> + </list> + </property> + </bean> + + <spring-security:authentication-provider user-service-ref="userDetailsService"/> + + <spring-security:user-service id="userDetailsService"> + <spring-security:user name="jim" password="jimspassword" authorities="ROLE_USER, ROLE_ADMIN"/> + <spring-security:user name="bob" password="bobspassword" authorities="ROLE_USER"/> + </spring-security:user-service> + +</beans> +<!-- END SNIPPET: example --> \ No newline at end of file Propchange: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml ------------------------------------------------------------------------------ svn:keywords = Rev Date Propchange: camel/trunk/tests/camel-itest/src/test/resources/org/apache/camel/itest/security/commonSecurity.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml