Updated Branches: refs/heads/master f22d973d7 -> 17b2306d9
CAMEL-6352: Added base64 option to camel-shiro so we can transfer tokens over JMS out of the box. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/17b2306d Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/17b2306d Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/17b2306d Branch: refs/heads/master Commit: 17b2306d92cd85fe9c5f1b17367858696046de31 Parents: f22d973 Author: Claus Ibsen <davscl...@apache.org> Authored: Sun May 12 12:45:13 2013 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Sun May 12 12:45:13 2013 +0200 ---------------------------------------------------------------------- .../component/shiro/security/ShiroConstants.java | 29 ++++ .../shiro/security/ShiroSecurityPolicy.java | 21 +++- .../shiro/security/ShiroSecurityTokenInjector.java | 20 +++- .../security/ShiroAuthenticationBase64Test.java | 107 +++++++++++++++ ...nticationReauthenticateFalseAndNewUserTest.java | 2 +- .../shiro/security/ShiroAuthenticationTest.java | 2 +- .../shiro/security/ShiroAuthorizationTest.java | 2 +- tests/camel-itest/pom.xml | 5 + .../apache/camel/itest/shiro/ShiroOverJmsTest.java | 96 +++++++++++++ .../src/test/resources/securityconfig.ini | 36 +++++ 10 files changed, 314 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroConstants.java b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroConstants.java new file mode 100644 index 0000000..745899e --- /dev/null +++ b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroConstants.java @@ -0,0 +1,29 @@ +/** + * 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.component.shiro.security; + +/** + * Shiro constants. + */ +public final class ShiroConstants { + + public static final String SHIRO_SECURITY_TOKEN = "SHIRO_SECURITY_TOKEN"; + + private ShiroConstants() { + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityPolicy.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityPolicy.java b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityPolicy.java index 9b13e03..b0e6b51 100644 --- a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityPolicy.java +++ b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityPolicy.java @@ -40,6 +40,7 @@ import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.Permission; +import org.apache.shiro.codec.Base64; import org.apache.shiro.config.Ini; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.crypto.AesCipherService; @@ -63,6 +64,7 @@ public class ShiroSecurityPolicy implements AuthorizationPolicy { private SecurityManager securityManager; private List<Permission> permissionsList; private boolean alwaysReauthenticate; + private boolean base64; public ShiroSecurityPolicy() { this.passPhrase = bits128; @@ -162,7 +164,15 @@ public class ShiroSecurityPolicy implements AuthorizationPolicy { } private void applySecurityPolicy(Exchange exchange) throws Exception { - ByteSource encryptedToken = ExchangeHelper.getMandatoryHeader(exchange, "SHIRO_SECURITY_TOKEN", ByteSource.class); + ByteSource encryptedToken; + if (isBase64()) { + String base64 = ExchangeHelper.getMandatoryHeader(exchange, ShiroConstants.SHIRO_SECURITY_TOKEN, String.class); + byte[] bytes = Base64.decode(base64); + encryptedToken = ByteSource.Util.bytes(bytes); + } else { + encryptedToken = ExchangeHelper.getMandatoryHeader(exchange, ShiroConstants.SHIRO_SECURITY_TOKEN, ByteSource.class); + } + ByteSource decryptedToken = getCipherService().decrypt(encryptedToken.getBytes(), getPassPhrase()); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decryptedToken.getBytes()); @@ -280,5 +290,12 @@ public class ShiroSecurityPolicy implements AuthorizationPolicy { public void setAlwaysReauthenticate(boolean alwaysReauthenticate) { this.alwaysReauthenticate = alwaysReauthenticate; } - + + public boolean isBase64() { + return base64; + } + + public void setBase64(boolean base64) { + this.base64 = base64; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityTokenInjector.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityTokenInjector.java b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityTokenInjector.java index 9ced6dc..e01eb66 100644 --- a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityTokenInjector.java +++ b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityTokenInjector.java @@ -37,6 +37,7 @@ public class ShiroSecurityTokenInjector implements Processor { private byte[] passPhrase; private ShiroSecurityToken securityToken; private CipherService cipherService; + private boolean base64; public ShiroSecurityTokenInjector() { this.passPhrase = bits128; @@ -69,7 +70,16 @@ public class ShiroSecurityTokenInjector implements Processor { } public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader("SHIRO_SECURITY_TOKEN", encrypt()); + ByteSource bytes = encrypt(); + + Object token; + if (isBase64()) { + token = bytes.toBase64(); + } else { + token = bytes; + } + + exchange.getIn().setHeader(ShiroConstants.SHIRO_SECURITY_TOKEN, token); } public byte[] getPassPhrase() { @@ -96,6 +106,14 @@ public class ShiroSecurityTokenInjector implements Processor { this.cipherService = cipherService; } + public boolean isBase64() { + return base64; + } + + public void setBase64(boolean base64) { + this.base64 = base64; + } + private static void close(ObjectOutput output) { try { output.close(); http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationBase64Test.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationBase64Test.java b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationBase64Test.java new file mode 100644 index 0000000..db0bbc1 --- /dev/null +++ b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationBase64Test.java @@ -0,0 +1,107 @@ +/** + * 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.component.shiro.security; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.IncorrectCredentialsException; +import org.apache.shiro.authc.LockedAccountException; +import org.apache.shiro.authc.UnknownAccountException; +import org.junit.Test; + +public class ShiroAuthenticationBase64Test extends CamelTestSupport { + + @EndpointInject(uri = "mock:success") + protected MockEndpoint successEndpoint; + + @EndpointInject(uri = "mock:authenticationException") + protected MockEndpoint failureEndpoint; + + private byte[] passPhrase = { + (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B, + (byte) 0x0C, (byte) 0x0D, (byte) 0x0E, (byte) 0x0F, + (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, + (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17}; + + @Test + public void testShiroAuthenticationFailure() throws Exception { + //Incorrect password + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("ringo", "stirr"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(0); + failureEndpoint.expectedMessageCount(1); + + template.send("direct:secureEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + @Test + public void testSuccessfulShiroAuthenticationWithNoAuthorization() throws Exception { + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("ringo", "starr"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(2); + failureEndpoint.expectedMessageCount(0); + + template.send("direct:secureEndpoint", shiroSecurityTokenInjector); + template.send("direct:secureEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + protected RouteBuilder createRouteBuilder() throws Exception { + final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy("src/test/resources/securityconfig.ini", passPhrase); + securityPolicy.setBase64(true); + + return new RouteBuilder() { + @SuppressWarnings("unchecked") + public void configure() { + onException(UnknownAccountException.class, IncorrectCredentialsException.class, + LockedAccountException.class, AuthenticationException.class). + to("mock:authenticationException"); + + from("direct:secureEndpoint"). + policy(securityPolicy). + to("log:incoming payload"). + to("mock:success"); + } + }; + } + + + private static class TestShiroSecurityTokenInjector extends ShiroSecurityTokenInjector { + + public TestShiroSecurityTokenInjector(ShiroSecurityToken shiroSecurityToken, byte[] bytes) { + super(shiroSecurityToken, bytes); + setBase64(true); + } + + public void process(Exchange exchange) throws Exception { + super.process(exchange); + exchange.getIn().setBody("Beatle Mania"); + } + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationReauthenticateFalseAndNewUserTest.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationReauthenticateFalseAndNewUserTest.java b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationReauthenticateFalseAndNewUserTest.java index 66dcc68..b0e8362 100644 --- a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationReauthenticateFalseAndNewUserTest.java +++ b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationReauthenticateFalseAndNewUserTest.java @@ -85,7 +85,7 @@ public class ShiroAuthenticationReauthenticateFalseAndNewUserTest extends CamelT } public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader("SHIRO_SECURITY_TOKEN", encrypt()); + exchange.getIn().setHeader(ShiroConstants.SHIRO_SECURITY_TOKEN, encrypt()); exchange.getIn().setBody("Beatle Mania"); } } http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationTest.java b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationTest.java index 118c62d..db8c483 100644 --- a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationTest.java +++ b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthenticationTest.java @@ -96,7 +96,7 @@ public class ShiroAuthenticationTest extends CamelTestSupport { } public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader("SHIRO_SECURITY_TOKEN", encrypt()); + exchange.getIn().setHeader(ShiroConstants.SHIRO_SECURITY_TOKEN, encrypt()); exchange.getIn().setBody("Beatle Mania"); } } http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthorizationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthorizationTest.java b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthorizationTest.java index d000db5..30cb9d6 100644 --- a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthorizationTest.java +++ b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroAuthorizationTest.java @@ -119,7 +119,7 @@ public class ShiroAuthorizationTest extends CamelTestSupport { } public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader("SHIRO_SECURITY_TOKEN", encrypt()); + exchange.getIn().setHeader(ShiroConstants.SHIRO_SECURITY_TOKEN, encrypt()); exchange.getIn().setBody("Beatle Mania"); } } http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/tests/camel-itest/pom.xml ---------------------------------------------------------------------- diff --git a/tests/camel-itest/pom.xml b/tests/camel-itest/pom.xml index 770d792..78a943a 100644 --- a/tests/camel-itest/pom.xml +++ b/tests/camel-itest/pom.xml @@ -170,6 +170,11 @@ <artifactId>camel-netty</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-shiro</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.apache.camel</groupId> http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java ---------------------------------------------------------------------- diff --git a/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java b/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java new file mode 100644 index 0000000..453b1ca --- /dev/null +++ b/tests/camel-itest/src/test/java/org/apache/camel/itest/shiro/ShiroOverJmsTest.java @@ -0,0 +1,96 @@ +/** + * 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.shiro; + +import javax.naming.Context; + +import org.apache.activemq.camel.component.ActiveMQComponent; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.shiro.security.ShiroSecurityPolicy; +import org.apache.camel.component.shiro.security.ShiroSecurityToken; +import org.apache.camel.component.shiro.security.ShiroSecurityTokenInjector; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.camel.util.jndi.JndiContext; +import org.junit.Test; + +public class ShiroOverJmsTest extends CamelTestSupport { + + private byte[] passPhrase = { + (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B, + (byte) 0x0C, (byte) 0x0D, (byte) 0x0E, (byte) 0x0F, + (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, + (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17}; + + @Test + public void testShiroOverJms() throws Exception { + getMockEndpoint("mock:error").expectedMessageCount(0); + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + ShiroSecurityToken token = new ShiroSecurityToken("ringo", "starr"); + + final ShiroSecurityTokenInjector injector = new ShiroSecurityTokenInjector(token, passPhrase); + injector.setBase64(true); + + template.request("direct:start", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("Hello World"); + injector.process(exchange); + } + }); + + assertMockEndpointsSatisfied(); + } + + @Override + protected Context createJndiContext() throws Exception { + JndiContext answer = new JndiContext(); + + // add ActiveMQ with embedded broker + ActiveMQComponent amq = ActiveMQComponent.activeMQComponent("vm://localhost?broker.persistent=false"); + amq.setCamelContext(context); + answer.bind("jms", amq); + return answer; + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy("src/test/resources/securityconfig.ini", passPhrase); + securityPolicy.setBase64(true); + + errorHandler(deadLetterChannel("mock:error")); + + from("direct:start") + .policy(securityPolicy) + .to("jms:queue:foo") + .to("mock:result"); + + from("jms:queue:foo") + .to("log:foo?showHeaders=true") + .policy(securityPolicy) + .to("mock:foo") + .transform().constant("Bye World"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/17b2306d/tests/camel-itest/src/test/resources/securityconfig.ini ---------------------------------------------------------------------- diff --git a/tests/camel-itest/src/test/resources/securityconfig.ini b/tests/camel-itest/src/test/resources/securityconfig.ini new file mode 100644 index 0000000..e72072e --- /dev/null +++ b/tests/camel-itest/src/test/resources/securityconfig.ini @@ -0,0 +1,36 @@ +# +# 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. +# + +[users] +# user 'ringo' with password 'starr' and the 'hero' role +ringo = starr, sec-level1 +george = harrison, sec-level2 +john = lennon, sec-level3 +paul = mccartney, sec-level3 + +[roles] +# 'sec-level3' role has all permissions, indicated by the wildcard '*' +sec-level3 = * + +# The 'sec-level2' role can do anything with access of permission readonly (*) to help +sec-level2 = zone1:* + +# The 'sec-level1' role can do anything with access of permission readonly +sec-level1 = zone1:readonly:* +