Christian HagerSoftware Engineer // Technical Director // Photographer

Integrating Spring Security and Eclipse RAP (Part 2)

In this part of the series I will explain how to add method security to the service level of our rap application. This tutorial builds on the results of part 1 of the series so this part should be read first.

By the way all steps described in this post will not only work using Eclipse RAP but as well using Eclipse RCP.

So what is necessary to add authorization to our services? First of all we need a service which we can secure. For this purpose we create two bundles representing this service. An API-bundle containing the services interface and a bundle containing the service implementation and the spring configuration to export the service to the OSGi registry. The service implementation will be quite simple. For now the services will have only one method returning a list of strings. In our application we modify our view to get the list of strings from our service and display them in a tableviewer. The application will now look like this:

Having set up our environment we can finally start to implement method security. For authorization to work in our service bundle we have to adapt the security service. Therefore we add the following configuration to the spring context of our security service.

<bean id="securityInterceptor"
  class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager" />
  <property name="securityMetadataSource">
   <bean
    class="org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource">
    <property name="methodSecurityMetadataSources">
     <list>
      <bean
       class="org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource">
       <constructor-arg>
        <bean
         class="org.springframework.security.access.expression.method.ExpressionBasedAnnotationAttributeFactory">
         <constructor-arg>
          <bean
           class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler" />
         </constructor-arg>
        </bean>
       </constructor-arg>
      </bean>
     </list>
    </property>
   </bean>
  </property>
  <property name="validateConfigAttributes" value="false" />
  <property name="rejectPublicInvocations" value="false" />
  <property name="accessDecisionManager">
   <bean id="accessDecisionManager"
    class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="decisionVoters">
     <list>
      <bean class="org.springframework.security.access.vote.RoleVoter" />
      <bean
       class="org.springframework.security.access.vote.AuthenticatedVoter" />
     </list>
    </property>
   </bean>
  </property>
 </bean>

The security interceptor we just configured will later decide if the logged in user is allowed to access our service methods. More information on spring security’s authorization architecture can be found here. Now we have to make the service available for other bundles.

<osgi:service ref="securityInterceptor">
 <osgi:interfaces>
  <value>org.aopalliance.intercept.MethodInterceptor</value>
  <value>org.aopalliance.aop.Advice</value>
 </osgi:interfaces>
</osgi:service>

Next we have to import the security interceptor service in our bundle where we want to apply method security and apply it to our service.

<osgi:reference id="securityInterceptor">
 <osgi:interfaces>
  <value>org.aopalliance.intercept.MethodInterceptor</value>
  <value>org.aopalliance.aop.Advice</value>
 </osgi:interfaces>
</osgi:reference>

<security:global-method-security pre-post-annotations="enabled" />

<bean id="someService" parent="serviceTemplate">
 <property name="target">
  <bean class="de.chager.sandbox.someservice.SomeServiceImpl" />
 </property>
</bean>

<bean id="serviceTemplate" abstract="true"
 class="org.springframework.aop.framework.ProxyFactoryBean">
 <property name="interceptorNames">
  <list>
   <value>securityInterceptor</value>
  </list>
 </property>
</bean>

At this point we can add spring security annotations to the service methods we want to secure.

@PreAuthorize( "hasRole('MY_ROLE')" )
public List readAllModelObjects()
{
...
}

Last but not least we have to adapt our security schema and configure the user service to read the authorization info. I won’t describe this here since the spring reference manual provides enough information on this topic.

That’s it. Now only authorized users should be able to use our secured service method.

Tags: , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *