Repository: camel Updated Branches: refs/heads/master 963ac1e45 -> 7965b3c62
CAMEL-7274 Support roles in the camel-shiro component. Thanks to Colm for the patch. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/7965b3c6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7965b3c6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7965b3c6 Branch: refs/heads/master Commit: 7965b3c629cfd85965ee210f9f9aa7a74d851bd0 Parents: 963ac1e Author: Raul Kripalani <[email protected]> Authored: Wed Mar 5 18:59:25 2014 +0000 Committer: Raul Kripalani <[email protected]> Committed: Wed Mar 5 18:59:25 2014 +0000 ---------------------------------------------------------------------- .../shiro/security/ShiroSecurityPolicy.java | 19 ++ .../shiro/security/ShiroSecurityProcessor.java | 17 +- .../security/ShiroRolesAuthorizationTest.java | 178 +++++++++++++++++++ .../src/test/resources/securityconfig.ini | 2 +- 4 files changed, 213 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/7965b3c6/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 35b4789..034e29b 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 @@ -45,15 +45,18 @@ public class ShiroSecurityPolicy implements AuthorizationPolicy { private byte[] passPhrase; private SecurityManager securityManager; private List<Permission> permissionsList; + private List<String> rolesList; private boolean alwaysReauthenticate; private boolean base64; private boolean allPermissionsRequired; + private boolean allRolesRequired; public ShiroSecurityPolicy() { this.passPhrase = bits128; // Set up AES encryption based cipher service, by default cipherService = new AesCipherService(); permissionsList = new ArrayList<Permission>(); + rolesList = new ArrayList<String>(); alwaysReauthenticate = true; } @@ -167,4 +170,20 @@ public class ShiroSecurityPolicy implements AuthorizationPolicy { public void setAllPermissionsRequired(boolean allPermissionsRequired) { this.allPermissionsRequired = allPermissionsRequired; } + + public List<String> getRolesList() { + return rolesList; + } + + public void setRolesList(List<String> rolesList) { + this.rolesList = rolesList; + } + + public boolean isAllRolesRequired() { + return allRolesRequired; + } + + public void setAllRolesRequired(boolean allRolesRequired) { + this.allRolesRequired = allRolesRequired; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/7965b3c6/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityProcessor.java b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityProcessor.java index fc42a06..bae7659 100644 --- a/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityProcessor.java +++ b/components/camel-shiro/src/main/java/org/apache/camel/component/shiro/security/ShiroSecurityProcessor.java @@ -182,13 +182,26 @@ public class ShiroSecurityProcessor extends DelegateAsyncProcessor { } } } + } else if (!policy.getRolesList().isEmpty()) { + if (policy.isAllRolesRequired()) { + authorized = currentUser.hasAllRoles(policy.getRolesList()); + } else { + for (String role : policy.getRolesList()) { + if (currentUser.hasRole(role)) { + authorized = true; + break; + } + } + } } else { - LOG.trace("Valid Permissions List not specified for ShiroSecurityPolicy. No authorization checks will be performed for current user."); + LOG.trace("Valid Permissions or Roles List not specified for ShiroSecurityPolicy. " + + "No authorization checks will be performed for current user."); authorized = true; } if (!authorized) { - throw new CamelAuthorizationException("Authorization Failed. Subject's role set does not have the necessary permissions to perform further processing.", exchange); + throw new CamelAuthorizationException("Authorization Failed. Subject's role set does " + + "not have the necessary roles or permissions to perform further processing.", exchange); } LOG.debug("Current user {} is successfully authorized.", currentUser.getPrincipal()); http://git-wip-us.apache.org/repos/asf/camel/blob/7965b3c6/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroRolesAuthorizationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroRolesAuthorizationTest.java b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroRolesAuthorizationTest.java new file mode 100644 index 0000000..ba57566 --- /dev/null +++ b/components/camel-shiro/src/test/java/org/apache/camel/component/shiro/security/ShiroRolesAuthorizationTest.java @@ -0,0 +1,178 @@ +/** + * 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 java.util.ArrayList; +import java.util.List; + +import org.apache.camel.CamelAuthorizationException; +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.junit.Test; + +public class ShiroRolesAuthorizationTest extends CamelTestSupport { + + @EndpointInject(uri = "mock:success") + protected MockEndpoint successEndpoint; + + @EndpointInject(uri = "mock:authorizationException") + 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 testShiroAuthorizationFailure() throws Exception { + // The user ringo has role sec-level1 + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("ringo", "starr"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(0); + failureEndpoint.expectedMessageCount(1); + + template.send("direct:secureEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + @Test + public void testSuccessfulAuthorization() throws Exception { + // The user george has role sec-level2 + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("george", "harrison"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(1); + failureEndpoint.expectedMessageCount(0); + + template.send("direct:secureEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + @Test + public void testSuccessfulAuthorizationForHigherScope() throws Exception { + // The user john has role sec-level3 + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("john", "lennon"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(1); + failureEndpoint.expectedMessageCount(0); + + template.send("direct:secureEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + @Test + public void testFailureAuthorizationAll() throws Exception { + // The user george has role sec-level2 but not sec-level3 + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("george", "harrison"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(0); + failureEndpoint.expectedMessageCount(1); + + template.send("direct:secureAllEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + @Test + public void testSuccessfulAuthorizationAll() throws Exception { + // The user paul has role sec-level2 and sec-level3 + ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("paul", "mccartney"); + TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); + + successEndpoint.expectedMessageCount(1); + failureEndpoint.expectedMessageCount(0); + + template.send("direct:secureAllEndpoint", shiroSecurityTokenInjector); + + successEndpoint.assertIsSatisfied(); + failureEndpoint.assertIsSatisfied(); + } + + + @Override + protected RouteBuilder[] createRouteBuilders() throws Exception { + + return new RouteBuilder[] {new RouteBuilder() { + public void configure() { + + List<String> rolesList = new ArrayList<String>(); + rolesList.add("sec-level2"); + rolesList.add("sec-level3"); + + final ShiroSecurityPolicy securityPolicy = + new ShiroSecurityPolicy("src/test/resources/securityconfig.ini", passPhrase, true); + securityPolicy.setRolesList(rolesList); + + onException(CamelAuthorizationException.class). + to("mock:authorizationException"); + + from("direct:secureEndpoint"). + policy(securityPolicy). + to("log:incoming payload"). + to("mock:success"); + } + }, new RouteBuilder() { + public void configure() { + + List<String> rolesList = new ArrayList<String>(); + rolesList.add("sec-level2"); + rolesList.add("sec-level3"); + + final ShiroSecurityPolicy securityPolicy = + new ShiroSecurityPolicy("src/test/resources/securityconfig.ini", passPhrase, true); + securityPolicy.setRolesList(rolesList); + securityPolicy.setAllRolesRequired(true); + + onException(CamelAuthorizationException.class). + to("mock:authorizationException"); + + from("direct:secureAllEndpoint"). + policy(securityPolicy). + to("log:incoming payload"). + to("mock:success"); + } + } + }; + } + + private static class TestShiroSecurityTokenInjector extends ShiroSecurityTokenInjector { + + public TestShiroSecurityTokenInjector(ShiroSecurityToken shiroSecurityToken, byte[] bytes) { + super(shiroSecurityToken, bytes); + } + + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(ShiroSecurityConstants.SHIRO_SECURITY_TOKEN, encrypt()); + exchange.getIn().setBody("Beatle Mania"); + } + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/7965b3c6/components/camel-shiro/src/test/resources/securityconfig.ini ---------------------------------------------------------------------- diff --git a/components/camel-shiro/src/test/resources/securityconfig.ini b/components/camel-shiro/src/test/resources/securityconfig.ini index e3c714b..d98f264 100644 --- a/components/camel-shiro/src/test/resources/securityconfig.ini +++ b/components/camel-shiro/src/test/resources/securityconfig.ini @@ -22,7 +22,7 @@ ringo = starr, sec-level1 george = harrison, sec-level2 john = lennon, sec-level3 -paul = mccartney, sec-level3 +paul = mccartney, sec-level3, sec-level2 [roles] # 'sec-level3' role has all permissions, indicated by the wildcard '*'
