[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [ecf-dev] remote service call authorization implemenation
|
On 10/05/2010 03:09 PM, Franky Bridelance wrote:
> Hi Scott, all,
>
> I would like to add remote service method authorization on ECF remote
> services. The goal of this email is twofold : first I would like to have
> some comments on the way I want to use the existing API's and second I
> would like to have your opinion on some API extension to make the method
> invocation authorization possible.
>
> Here's a description of what I would like to achieve:
> - Client connects to server with some credentials
> - Server authenticates the client with the given credentials, retrieves
> the authorization roles for the given credentials and links those
> authorization roles to the client container ID
> - For each remote service call done from the client, server checks if
> service method call is authorized for the given client container ID
> - Server cleans up relation between authorization roles and client
> container id when client disconnects (or user logs off)
> FYI: The real authentication and authorization wiill be done by spring
> security, ECF generic will be used to provide the information needed for
> authentication and authorization.
>
> There's enough API in ECF to provide information for the authentication
> part:
>
> - Client creates container
> - Get ISharedObjectContainerClient interface from the container.
> - Set an implementation of IConnectInitiatorPolicy on
> ISharedObjectContainerClient that will return the needed connect data to
> pass to the server
> - Create an implementation of IConnectContext containing the needed
> connect data
> - call connect method on container with the own IConnectContext
> implementation
>
> - Server creates container
> - Get ISharedObjectContainerGroupManager interface from the container
> - Set an implementation of IConnectHandlerPolicy on
> ISharedObjectContainerGroupManager that will
> + get the connect data
> + use this connect data to authenticate (via spring security)
> + if authentication fails throw an exception
> + if authentication succeeds: retrieve the authorization roles
> (via spring security) for the authenticated user and link this to the
> client container ID (fromID arg in IConnectHandlerPolicy.checkConnect)
> --> question: is the client container ID unique?
>
> For the authorization of remote service call there's as far as I know no
> API available, so I checked what is needed and came up with a proposal
> API. I tried to make the API generic enough to support several
> authorization implementations, provider independent and at the same time
> fitting ECF generic implementation and spring security integration.
>
> So what I need is a way to intercept the remote service call at the
> server side to do some authorization checking (or in my case to provide
> the needed information to spring security). It's important to have the
> interception "around" the remote service call such that authorization
> specific code can be performed before and after the remote service call
> (in my case some authorization info would be put before the service call
> for spring security and cleaned up after the call). In ECF generic
> implementation, what I think would be the right place (but here I'm
> maybe looking too much at how to integrate with spring security) is in
> RegistrySharedObject.executeRequest within the run method of the created
> IProgressRunnable around "localRegistration.callService(call)". I have
> three reasons to place the authorization interception there:
> 1. If an exception must be thrown because the call is not authorized the
> exception will be handled correctly.
> 2. We're sure not to have any thread context switching from this point
> to the local service method call (at least not in the ECF layer, you can
> still have thread context switching within the service method call but
> that's application specific).
> 3. It's the last method having all information needed for authorization:
> ID of the caller (client container), method call and service on which
> call is performed.
>
> For the API, I was thinking to have a policy interface (like the
> IConnectInitiatorPolicy and IConnectHandlerPolicy) that can be set on
> IRemoteServiceContainerAdapter interface (question: is this the right
> place? Because IRemoteServicecontainerAdapter looks more a client
> oriented interface while the IRemoteServiceCallPolicy is more a server
> thing), for example:
>
> public interface IRemoteServiceCallPolicy {
> public Object callWithAuthorization(IRemoteServiceRegistration
> registration, IRemoteCall call, ID fromID) throws Exception;
> }
>
> and on IRemoteServiceContainerAdapter there should be a new method:
>
> public void setRemoteServiceCallPolicy(IRemoteServiceCallPolicy policy);
>
> The last thing to do would then be to implement the method
> setRemoteServiceCallPolicy on RegistrySharedObject class should then and
> Update the method RegistrySharedObject.executeRequest:
> try {
> if (remoteSeviceCallPolicy != null) {
> result =
> remoteServiceCallPolicy.callWithAuthorization(localregistration, call,
> responseTarget);
> } else {
> result = localRegistration.callService(call);
> }
> response = ...
> ...
> } catch...
>
> There's one thing that bothers me with this solution: an implementation
> of the IRemoteServicecallPolicy.callWithAuthorization would need to have
> ECf generic internal knowledge to be able to call
> localRegistration.callService method because this method is not part of
> the IRemoteServiceRegistration interface.
>
> Another (maybe better) solution could be to have an interface with a pre
> invocation hook and a post invocation hook. The preinvocation hook can
> then be used to authorize the service method call and the post
> invocation hook can be used to clean up authorization data that was set
> up at the preinvocation hook.
> public interface IRemoteServiceCallPolicy {
> public void preInvocationHook(IRemoteServiceRegistration
> registration, IRemoteCall call, ID fromID) throws Exception;
> public void postInocationHook(IRemoteServiceRegistration
> registration, IRemoteCall call, ID fromID) throws Exception;
> }
>
> RegistrySharedObject.executeRequest method should then be changed to:
> try {
> if (remoteServiceCallPolicy != null) {
> remoteServiceCallPolicy.preInvocationHook(localregistration, call,
> responseTarget);
> }
> result = localRegistration.callService(call);
> response = ...
> } catch ... {
> ...
> } finally {
> if (remoteServiceCallPolicy != null) {
> remoteServiceCallPolicy.postInvocationHook(localregistration,
> call, responseTarget);
> }
> }
>
> What's you opinion on this?
>
> br,
>
> Franky
Hi Franky,
thanks for your efforts. Do you happen to have a patch already that you
could share with us. Makes it a lot easier to understand the changes. :-)
Thanks
Markus