October 6th, 2009, 02:58 AM
SOA Design with External API
I am in the early planning stages for a web project which will have, among other things, a SOA backend with selected portions of the components opened up as an externally-accessible API. The trick is that we need to have a single access point for the entire system, so that an external partner would access it via, say, api.ourcompany.com.
Suppose for a moment that the system consists of three simple components, each with two simple methods. Of those, let's say we want only three of them to be public. So we have something like:
Further, let's suppose we want at the very least component-level security, if not method-level security (or maybe the option for either). We'd like to use OAuth in either case to keep things straightforward for our partners.
In the past, I've implemented such systems by writing a "Base Service" package upon which each component is built. The base package provides the security protocol, request signing, and so on, and is responsible for interfacing with a separate ACL-driven service which checks method security. So when some partner (or internal subsystem) calls a service, the base service knows to check the ACL to see if this system is authorized to call whatever method, and then caches that knowledge for a few minutes.
Then for the single endpoint, I'd just run a caching proxy with a redirector like Squid/Jesred to rewrite requests, like:
Would be rewritten to:
Now this kind of a set up has been proven to work for me, but I am wondering if there is a better way to do it. In particular I was thinking of exploring a single "Controller" which encapsulates the method security layer and handles the redirection/rewriting of external requests itself. In other words, in the old setup, any external request will make it all the way to the actual service on our end before it is checked for access rights and so on, whereas under this new design the controller layer would immediately bounce any unauthorized request. In theory this would be more secure, and would also reduce the complexity of the services themselves, since the security layer would be "above" them.
Anyway, I am curious if anybody has any experience designing in this area, or maybe some good reasons to go one way or another, or even a reference example or two. Most of the books I've seen on these topics don't delve this far into it, or advocate using a third-party access rights management solution. We are open to that, but want to lay out a best case/ideal scenario first and then go from there.
October 6th, 2009, 01:01 PM
The way I would model communication is through a broker and add basic security support to it. The services could then opt-in via configuration or annotations, as well as supply specialized policies for how to perform the check. A read-only request/security context with the most core information (userId, companyId, etc) would be passed along as well.
The security check should be performed at both the client and server side, but no matter what at the server-side. The client-side would act like an optimization, for those checks that it can do locally, to fail-fast rather than making a remote call.
There are a lot of parallels with distributed systems and Operating Systems, so its worth looking into and extending those ideas. For security aspects, I would read up on how OS's handle them in terms of roles, acls, etc. That should help reduce the likelihood of making innocent mistakes that create security holes.