6.2.3.
Writing an OGSA-DAI Activity that has Access to the Current User's Identity Details
Up one level
Overview
In some cases, an Activity executed by the OGSA-DAI service may require the identity details (X.509 distinguished name, additional tokens, etc) of the client that invoked the service. These details are available from the user's SubjectDescription object. This is stored in a HashMap keyed off the unique name of each activity.
Example Code
The following is an example of using the current users SubjectDescription to make a call on another GRIA OGSA-DAI Service. The example is of the processBlock method in an OGSA-DAI activity implementation.
public void processBlock() { StateRepository repos = new MemoryStateRepository(); EndpointReferenceType epr = ConversationID.getEPR("https://bodegas.it-innovation.soton.ac.uk:8443/gria-ogsadai-service/services/OgsaDaiSubscription#ff808181-14fede48-0114-fef342c9-0006"); OgsaDaiSubscriptionConversation convo = repos.getOrCreateObject(OgsaDaiSubscriptionConversation.class, epr); try { //getName() returns a unique string for each activity instance. //The SubjectDescription of the user that made the perform call that initiated the activity //Is stored in the OgsaDaiServiceImpl.activityClientMap SubjectDescription client = OgsaDaiServiceImpl.activityClientMap.get(getName()); convo.checkPolicyRule(client,"perform"); } catch (RemoteException e) { setError(e); } }
Example Scenario
One specific example where the client's credentials are required is when the OGSA-DAI service is acting on behalf of many clients, for instance if the OGSA-DAI service is installed as an intermediary between the client and the final GRIA OGSA-DAI service. This situation is represented in a simplified form in the following figure.
A GRIA OGSA-DAI service acting as an intermediary
In the figure, Client A sends a request to Service B (step 1). Service B executes an OGSA-DAI activity that requires access to Service C (for instance, Service B may be in place to rewrite the query in a different query language). For Service B to access Service C (step 3) it must be authorised in the usual way on Service C, but it is a security loop-hole if step 3 is carried out with no further access control checks. In step 2, Service B checks that Client A is permitted to access Service C and only if Client A can access Service C will Service B access Service C on Client A's behalf.
There is no context displayed in the figure, instead the context of each call is listed below:
- perform (Client A to Service B)
- Identity: Client A's X.509 identity plus additional tokens from membership groups etc
- Resource: The query is performed on a data resource subscription from Service B
- Parameters:
- The query
- The endpoint reference for Client A's data resource subscription at Service C
- checkPolicyRule (Service B to Service C)
- Identity: Service B's X.509 identity
- Resource: The endpoint reference for Client A's data resource subscription at Service C
- Parameters
- Client A's identity (found using the activityClientMap as shown above)
- The operation name ("perform")
- perform (Service B to Service C)
- Identity: Service B's X.509 identity
- Resource: The endpoint reference for Client A's data resource subscription at Service C
- Parameters
- The query Service B wants to execute on Client A's behalf
For this scenario to operate, Client A will have to authorise Service B to use Client A's data resource subscription at Service C (e.g. as a "delegate").
With these steps in place Client A can only access data at Service C that Client A is permitted to see. If step 2 is not used then a different client ("Client Z") who was authorised on Service B but not Service C, could find out the endpoint reference of Client A's subscription at Service C and perform the same query on Service B as above. Service B would then blindly perform a query on Service C and return the results to Client Z, exposing the data.
