Hi Franky,
First, I want to say...nice job! This will make a very nice
addition to ECF remote services.
I should say though that we are approaching ECF 3.4 minor release
(hopefully at the end of this month), and it may not be possible to
get these API changes (and consequent changes to provider impls)
decided upon and incorporated into the ECF 3.4 release. We've got
to have an EF review and stuff like that as part of the release...so
I just want to make sure you know that if we don't get this work
into that release it's simply because of the mechanics of the releng
process...and no reflection on the value of this work. I'm sure
that we will be able to get it into later releases in some form.
With my comments below, I'm going to focus on the API additions
rather than the implementation...i.e. to the
org.eclipse.ecf.remoteservice package...rather than the specifics of
the implementation. The reason for this is that I think that the
API additions/changes are the most important to think carefully
about...as API is forever :), while implementation bugs can be
relatively easily fixed.
So...see further comments inline.
On 10/5/2010 6:09 AM, Franky Bridelance wrote:
Hi Scott, all,
<stuff deleted>
- 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?
Yes.
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.
This is great...exactly right about the need for generality and
cross-provider support.
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.
Yes, understood.
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),
Yes, it is the right place for this, I believe.
IRemoteServiceContainerAdapter has both remote service 'host' (aka
server), and 'consumer' (aka client) methods on it...as there isn't
any assumed asymmetry in the remote service API (all just remote
service api supporters...able to both register remote services and
access the remote service).
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);
<stuff deleted>
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.
Hmm. One possibility is that the IRemoteServiceRegistration
interface be enhanced (i.e. to include a callService method).
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;
}
<stuff deleted>
What's you opinion on this?
This second approach is interesting. It's perhaps a little more
complex (two methods rather than one), but in some ways it's more
similar to the approach taken in Java 2 security (i.e. the security
manager).
My immediate inclination is to prefer the first one (for
simplicity). But I would like to discuss with you (Franky) in
public (i.e. here on the mailing list) a little bit about your use
case...to try to understand which would work better for this and
other use cases.
So if you don't mind me asking in public...what are you doing inside
of IRemoteServiceCallPolicy for your use case? Is one of the two
approaches you list above simpler in your use case? If so, which
one?
Thanks again for doing this...and for considering contributing back
to the ECF project. This will help all in the community.
Scott
|