Shiro Security Basics
Shiro security is applied on a route using a Camel Policy. A Policy in Camel utilizes a strategy pattern for applying interceptors on Camel Processors. It offering the ability to apply cross-cutting concerns (for example. security, transactions etc) on sections/segments of a camel route.
To employ Shiro security on a camel route, a ShiroSecurityPolicy object must be instantiated with security configuration details (including users, passwords, roles etc). This object must then be applied to a camel route. This ShiroSecurityPolicy Object may also be registered in the Camel registry (JNDI or ApplicationContextRegistry) and then utilized on other routes in the Camel Context.
Configuration details are provided to the ShiroSecurityPolicy using an Ini file (properties file) or an Ini object. The Ini file is a standard Shiro configuration file containing user/role details as shown below
A Shiro Ini File containing configuration details
[users] # user 'ringo' with password 'starr' and the 'sec-level1' 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:*
Applying Shiro Authentication on a Camel Route
An example of using the information in the Ini file to apply authentication security is shown below. In the following example, the ShiroSecurityPolicy, permits incoming message exchanges containing a encrypted SecurityToken in the Message Header to proceed further following proper authentication. The SecurityToken object contains a Username/Password details that are used to determine where the user is a valid user.
protected RouteBuilder createRouteBuilder() throws Exception { final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy("./src/test/resources/securityconfig.ini", passPhrase); return new RouteBuilder() { public void configure() { onException(UnknownAccountException.class). to("mock:authenticationException"); onException(IncorrectCredentialsException.class). to("mock:authenticationException"); onException(LockedAccountException.class). to("mock:authenticationException"); onException(AuthenticationException.class). to("mock:authenticationException"); from("direct:secureEndpoint"). to("log:incoming payload"). policy(securityPolicy). to("mock:success"); } }; }
Applying Shiro Authorization on a Camel Route
The example below shows how authorization can be applied on a camel route by associating a Permissions List with the ShiroSecurityPolicy. The Permissions List specifies the permissions necessary for the user to proceed with the execution of the route segment. If the user does not have the proper permission set, the request is not authorized to continue any further.
protected RouteBuilder createRouteBuilder() throws Exception { ListpermissionsList = new ArrayList (); Permission permission = new WildcardPermission("zone1:readwrite:*"); permissionsList.add(permission); final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy("./src/test/resources/securityconfig.ini", passPhrase, true, permissionsList); return new RouteBuilder() { public void configure() { onException(CamelAuthorizationException.class). to("mock:authorizationException"); from("direct:secureEndpoint"). to("log:incoming payload"). policy(securityPolicy). to("mock:success"); } }; }
Sending requests to routes secured by a ShiroSecurityPolicy
Messages and Message Exchanges sent along the camel route where the security policy is applied need to be accompanied by a SecurityToken in the Exchange Header. The SecurityToken is an encrypted object that holds a Username and Password. The SecurityToken is encrypted using AES 128 bit security by default and can be changed to any cipher of your choice.
Given below is an example of how a request may be sent using a ProducerTemplate in Camel along with a SecurityToken
@Test public void testSuccessfulShiroAuthenticationWithNoAuthorization() throws Exception { //Incorrect password ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("ringo", "stirr"); TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); successEndpoint.expectedMessageCount(1); failureEndpoint.expectedMessageCount(0); template.send("direct:secureEndpoint", shiroSecurityTokenInjector); successEndpoint.assertIsSatisfied(); failureEndpoint.assertIsSatisfied(); }
Complete Examples
ShiroAuthenticationTest
ShiroAuthorizationTest
Further Details
The submission for this component is available for comment and review at
http://issues.apache.org/activemq/browse/CAMEL-2779