Supporting service-based multi realm authentication and authorization

by | Apr 21, 2015 | Developer | 0 comments

Security is often a forgotten concern in Big Data environments. However, as these technologies are being embraced by companies with sensitive data (think, for example, about banks or insurance companies), security is a growing requirement. In Stratio, we are aware of our clients’ needs, so we are studying the development of an integrated security solution for our platform.

We have chosen Apache Shiro as the main component of our future security solution, because it is a well-known and tested platform that (almost) fits our needs. Of course, we have performed some extensions for supporting specific requirements in our platform. First of all, we aim to provide our security API in a distributed and scalable way, so we have implemented an actor system based in Akka for managing the underlying Apache Shiro library. Also, as we expect to provide users with fine-grained permissions and due to the amount of elements expected (i.e., a huge numbers of users with different permissions on a huge numbers of tables), we also have implemented a distributed cache for improving the performance of the system. Those points will be treated in future posts.


Authentication and authorization

Shiro supports out-of-the-box multiple realm authentication and authorization. But we need to have the ability to provide that for each or our platform’s modules. We have implemented our own custom Shiro Realm supporting authentication and authorization, and aggregating an arbitrary number of realms (LDAPJDBCfile-based realms, or custom realms) performing an authentication strategy over all of them and authorizing the platforms users. A remarkable point is that, with our current custom realm implementation, the aggregating realms can share specific authentication and authorization systems. For example, service1 and service2 realms can reuse the same LDAP for performing authentication and the same JDBC repository for permission checking.


Creating the custom StratioRealm

Since we want to support both authentication and authorization, our realm must extend Shiro class AuthorizingRealm (which also extends AuthenticatingRealm), and override the doGetAuthenticationInfo and doGetAuthorizationInfo methods, where we will perform our authentication and authorization operations. Our StratioRealm also includes a service name attribute and two lists of authenticating and authorizing realms.
This way, we achieve our original goal of supporting multiple realm security operations for each of our platform modules.

Within the overridden methods, we perform authentication and authorization against each one of the configured realms and return a merged result (principals, in the case of authentication; roles and its associated permissions in the case of authorization). We found one caveat here: the method performing authorization for specific authorization realms is protected, so we can’t call it directly inside our code. Our workaround is implementing a wrapper for AuthorizingRealm with the same package name, and exposing the desired methods as public there.


Implementing an AuthenticationStrategy

We have introduced a new parameter (the service/module name) in the authentication process. Thus, we have to create a specific authentication strategy to take this into account. As we did with the previous StratioRealm, we must extends a Shiro class (AbstractAuthenticationStrategy) and implement and override its methods. In this case, we expect to receive an authentication token containing an username, a password, and a service name. We have included an additional condition: that service name must match the service name configured in the realm we want to authenticate against. Otherwise, we throw an AuthenticationException and the user is not allowed to use the system. Also, with our current implementation, we enforce the user authentication in every defined subrealm, throwing an error otherwise, but this behaviour can be also customized.


Sample configuration

The last step for having our custom solution working is specifying the configuration we want Shiro to use for our set of realms. A simple example of Shiro configuration file:


Conclusions and future work

Some conclusions extracted from this post:

  • Security has a growing value for Big Data systems.
  • There are several interesting open source projects that might be used for securizing our systems.
  • It is more than likely that you should extend some points of your tool of choice. We have done it with our solution adding actor support and customizing the authentication and authorization processes.
  • We expect to develop an integrated user management solution, with capabilities for quarantining users, expiring sessions and fully configuring the authentication and authorization realms.
  • Another step is developing a solution for auditing every user operation inside the platform.

We look forward to reading your questions and suggestions. Feel free to comment!