edu.uiuc.ncsa.security.delegation.client.DelegationService Maven / Gradle / Ivy
package edu.uiuc.ncsa.security.delegation.client;
import edu.uiuc.ncsa.security.delegation.client.request.*;
import edu.uiuc.ncsa.security.delegation.client.server.AGServer;
import edu.uiuc.ncsa.security.delegation.client.server.ATServer;
import edu.uiuc.ncsa.security.delegation.client.server.PAServer;
import edu.uiuc.ncsa.security.delegation.services.Request;
import edu.uiuc.ncsa.security.delegation.services.Response;
import edu.uiuc.ncsa.security.delegation.services.Server;
import edu.uiuc.ncsa.security.delegation.storage.Client;
import edu.uiuc.ncsa.security.delegation.token.AuthorizationGrant;
import edu.uiuc.ncsa.security.delegation.token.Verifier;
import java.net.URI;
import java.util.Map;
/**
* THE service API. This is a facade for the various bits of delegation a client needs
* to get a protected asset (mostly we are interested in certificates).
* The underlying messages might mutate, but the overall patterns do not vary much at all.
* This abstraction layer keeps those patterns and shoves everything that is implementation
* specific into separate modules. The nomenclature used throughout is OAuth 2.0:
*
* - Asset = the thing that is being delegated. Here usually it is a certificate.
* - Client = the application requesting delegation
* - Resource Owner = The person (or maybe thing) who owns the asset
* - Authorization Server = The server that authorizes access to asset
* - Resource Server = The server that actually has the asset
*
* Note that asset, protected asset and resource are all pretty much used interchangeably.
* The steps then are as follows.
*
* - A resource owner tells a client to use a protected resource
* - The client starts the request cycle. It gets an authorization grant and a uri pointing it to the authorization server.
* - The owner grants authorization.
* - The authorization server notifies the client via a callback, getting the authorization grant (which identifies the transaction)
* and a verifier showing resource owner approval.
* - The client requests the asset using the grant and verifier.
*
* This is based on OAuth and it does the complete, specification compliant exchanges. However, since we have a
* few special cases which vastly streamline this, only a very simple API is really what a client needs.
* Generally applications will
* write to this to get their functionality and only in exceptional cases will
* use the implementations of the underlying service. Direct references to protocols (e.g. OAuth 1.0a)
* are inherently fragile and will break at some point, e.g. when trying to use OAuth 2.0. One of the strongest
* arguments for doing it this way is that services may have to support several types of requests (OAuth 1 and 2)
* and this design allows for keeping multiple instances cleanly separated.
*
Created by Jeff Gaynor
* on Apr 4, 2011 at 3:51:41 PM
*/
public abstract class DelegationService implements Server {
protected DelegationService(AGServer agServer,
ATServer atServer,
PAServer paServer
) {
this.agServer = agServer;
this.atServer = atServer;
this.paServer = paServer;
}
/**
* Starts the delegation process. This requests that the server permit delegation.
*
* @return
*/
public DelegationResponse processDelegationRequest(DelegationRequest delegationRequest) {
AGRequest agReq = new AGRequest();
agReq.setClient(delegationRequest.getClient());
agReq.setParameters(delegationRequest.getParameters());
AGResponse agResp = (AGResponse) getAgServer().process(agReq);
DelegationResponse delResp = new DelegationResponse(agResp.getAuthorizationGrant());
delResp.setRedirectUri(createRedirectURL(delegationRequest, agResp));
return delResp;
}
protected ATResponse getAT(AuthorizationGrant grant, Client client, Map parameters) {
return getAT(grant, client, parameters);
}
protected ATResponse getAT(AuthorizationGrant grant, Verifier v, Client client, Map parameters) {
ATRequest atr = new ATRequest();
atr.setAuthorizationGrant(grant);
atr.setVerifier(v);
atr.setClient(client);
atr.setParameters(parameters);
ATResponse atresp = (ATResponse) getAtServer().process(atr);
return atresp;
}
public ATResponse getAT(DelegatedAssetRequest delegationAssetRequest) {
return getAT(delegationAssetRequest.getAuthorizationGrant(),
delegationAssetRequest.getVerifier(),
delegationAssetRequest.getClient(),
delegationAssetRequest.getParameters());
}
/**
* Gets the asset once the delegation has been approved. This will typically involve getting tokens as
* needed from the authorization server then accessing the resource server, so this actually does two
* legs in the protocol in quick succession. If you need to do these separately, then invoke
* them as
* getAT
* getCert
* with the correct parameters.
*
* @return
*/
public DelegatedAssetResponse processAssetRequest(DelegatedAssetRequest delegationAssetRequest) {
// First step is to get the access token
ATResponse atResp = getAT(delegationAssetRequest);
// Then get the cert
return getCert(atResp, delegationAssetRequest.getClient(), delegationAssetRequest.getAssetParameters());
}
public DelegatedAssetResponse getCert(ATResponse atResponse, Client client, Map assetParameters) {
PARequest paReq = new PARequest();
paReq.setClient(client);
paReq.setAccessToken(atResponse.getAccessToken());
paReq.setParameters(assetParameters);
PAResponse paResp = (PAResponse) getPaServer().process(paReq);
DelegatedAssetResponse dap = new DelegatedAssetResponse(paResp.getProtectedAsset());
dap.setAdditionalInformation(paResp.getAdditionalInformation());
return dap;
}
public abstract URI createRedirectURL(DelegationRequest delegationAssetRequest, AGResponse agResp);
public Response process(Request request) {
return request.process(this);
}
/**
* The authorization server. This server issues access tokens.
*
* @return
*/
public ATServer getAtServer() {
return atServer;
}
/**
* The resource server. This server hosts the protected assets.
*
* @return
*/
public PAServer getPaServer() {
return paServer;
}
ATServer atServer;
/**
* This server issues the authorization grant that starts the delegation process.
*
* @return
*/
public AGServer getAgServer() {
return agServer;
}
AGServer agServer;
PAServer paServer;
}