
edu.uiuc.ncsa.oa4mp.oauth2.client.OA2MPService Maven / Gradle / Ivy
package edu.uiuc.ncsa.oa4mp.oauth2.client;
import edu.uiuc.ncsa.myproxy.oa4mp.client.*;
import edu.uiuc.ncsa.security.core.exceptions.GeneralException;
import edu.uiuc.ncsa.security.core.exceptions.NFWException;
import edu.uiuc.ncsa.security.core.util.DateUtils;
import edu.uiuc.ncsa.security.delegation.client.request.*;
import edu.uiuc.ncsa.security.delegation.token.AuthorizationGrant;
import edu.uiuc.ncsa.security.delegation.token.MyX509Certificates;
import edu.uiuc.ncsa.security.delegation.token.Verifier;
import edu.uiuc.ncsa.security.oauth_2_0.NonceHerder;
import edu.uiuc.ncsa.security.oauth_2_0.OA2Constants;
import edu.uiuc.ncsa.security.oauth_2_0.OA2Scopes;
import edu.uiuc.ncsa.security.oauth_2_0.UserInfo;
import edu.uiuc.ncsa.security.oauth_2_0.client.ATResponse2;
import edu.uiuc.ncsa.security.oauth_2_0.client.DS2;
import edu.uiuc.ncsa.security.oauth_2_0.server.OA2Claims;
import edu.uiuc.ncsa.security.util.pkcs.CertUtil;
import edu.uiuc.ncsa.security.util.pkcs.KeyUtil;
import edu.uiuc.ncsa.security.util.pkcs.MyPKCS10CertRequest;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import java.security.KeyPair;
import java.util.Date;
import java.util.Map;
import static edu.uiuc.ncsa.myproxy.oa4mp.client.ClientEnvironment.CALLBACK_URI_KEY;
/**
* Created by Jeff Gaynor
* on 2/21/14 at 2:50 PM
*/
public class OA2MPService extends OA4MPService {
@Override
public void preGetCert(Asset asset, Map parameters) {
super.preGetCert(asset, parameters);
OA2Asset a = (OA2Asset) asset;
parameters.put(ClientEnvironment.CERT_REQUEST_KEY, Base64.encodeBase64String(asset.getCertReq().getEncoded()));
if (!parameters.containsKey(getEnvironment().getConstants().get(CALLBACK_URI_KEY))) {
parameters.put(getEnvironment().getConstants().get(CALLBACK_URI_KEY), getEnvironment().getCallback().toString());
}
if (0 <= getEnvironment().getCertLifetime()) {
parameters.put(ClientEnvironment.CERT_LIFETIME_KEY, getEnvironment().getCertLifetime());
}
if (asset.getCertificates() != null) {
// We have some, so restart the sequence to get more.
MyPKCS10CertRequest certRequest = asset.getCertReq();
KeyPair keyPair = null;
if (certRequest == null) {
// ok... generate a new keypair
try {
keyPair = KeyUtil.generateKeyPair();
} catch (Throwable e) {
String msg = "Unable to generate a new keypair.";
getEnvironment().getMyLogger().warn(msg, e);
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new GeneralException(msg, e);
}
asset.setPrivateKey(keyPair.getPrivate());
} else {
// need to public key.
keyPair = new KeyPair(certRequest.getPublicKey(), asset.getPrivateKey());
}
if (asset.getPrivateKey() == null) {
String msg = "Error: The private key is missing. The internal state of the asset is invalid";
NFWException x = new NFWException((msg));
getEnvironment().getMyLogger().warn(msg, x);
throw x;
}
try {
asset.setCertReq(CertUtil.createCertRequest(keyPair));
} catch (Throwable t) {
String msg = "Error: could not create cert request.";
getEnvironment().getMyLogger().warn(msg, t);
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new GeneralException(msg, t);
}
}
}
@Override
protected Map getATParameters(Asset asset, AuthorizationGrant ag, Verifier v) {
Map m = super.getATParameters(asset, ag, v);
OA2Asset a = (OA2Asset) asset;
m.put(OA2Constants.NONCE, a.getNonce());
m.put(OA2Constants.STATE, a.getState());
return m;
}
@Override
public void preRequestCert(Asset asset, Map parameters) {
// do nothing here in this case. Protocol says add cert req before getCert.
if (!parameters.containsKey(getEnvironment().getConstants().get(CALLBACK_URI_KEY))) {
parameters.put(getEnvironment().getConstants().get(CALLBACK_URI_KEY), getEnvironment().getCallback().toString());
}
OA2Asset a = (OA2Asset) asset;
a.setState(NonceHerder.createNonce());
a.setNonce(NonceHerder.createNonce());
// Next is for testing exception handling on the server. This creates an unsupported request which should fail everytime.
//parameters.put(OA2Constants.REQUEST, "My_request");
parameters.put(OA2Constants.RESPONSE_TYPE, OA2Constants.AUTHORIZATION_CODE);
//parameters.put(OA2Constants.CLIENT_ID, delegationRequest.getClient().getIdentifierString());
parameters.put(OA2Constants.SCOPE, OA2Scopes.SCOPE_OPENID); // only openid
//parameters.put(OA2Constants.REDIRECT_URI, delegationRequest.getParameters().get(OA2Constants.REDIRECT_URI));
parameters.put(OA2Constants.STATE, a.getState()); // random state is ok.
parameters.put(OA2Constants.NONCE, a.getNonce());
parameters.put(OA2Constants.PROMPT, OA2Constants.PROMPT_LOGIN);
}
@Override
public void postRequestCert(Asset asset, OA4MPResponse oa4MPResponse) {
super.postRequestCert(asset, oa4MPResponse);
OA2Asset a = (OA2Asset) asset;
}
public OA2MPService(ClientEnvironment environment) {
super(environment);
}
public ATResponse2 getAccessToken(OA2Asset asset, AuthorizationGrant ag) {
DelegatedAssetRequest dar = new DelegatedAssetRequest();
dar.setAuthorizationGrant(ag);
dar.setClient(getEnvironment().getClient());
Map m1 = getATParameters(asset, ag, null);
dar.setParameters(m1);
ATResponse2 atResponse2 = (ATResponse2) getEnvironment().getDelegationService().getAT(dar);
asset.setIssuedAt((Date) atResponse2.getParameters().get(OA2Claims.ISSUED_AT));
asset.setUsername((String) atResponse2.getParameters().get(OA2Claims.SUBJECT));
asset.setAccessToken(atResponse2.getAccessToken());
asset.setRefreshToken(atResponse2.getRefreshToken());
getAssetStore().save(asset);
return atResponse2;
}
public AssetResponse getCert(OA2Asset a, ATResponse2 atResponse2) {
Map m1 = getAssetParameters(a);
preGetCert(a, m1);
DelegatedAssetResponse daResp = getEnvironment().getDelegationService().getCert(atResponse2, getEnvironment().getClient(), m1);
AssetResponse par = new AssetResponse();
MyX509Certificates myX509Certificate = (MyX509Certificates) daResp.getProtectedAsset();
par.setX509Certificates(myX509Certificate.getX509Certificates());
// OAuth 2/OIDC returns this with the access token.
// par.setUsername(daResp.getAdditionalInformation().get("username"));
postGetCert(a, par);
a.setCertificates(par.getX509Certificates());
getEnvironment().getAssetStore().save(a);
return par;
}
@Override
protected AssetResponse getCert(Asset a, AuthorizationGrant ag, Verifier v) {
OA2Asset asset = (OA2Asset) a;
ATResponse2 atResp = getAccessToken(asset, ag);
return getCert(asset, atResp);
}
/**
* This will take the identifier and make the necessary calls to the service to update the refresh
* token and access token. This returns the asset or null if no such asset exists.
*
* @param identifier
*/
public OA2Asset refresh(String identifier) {
OA2Asset asset = (OA2Asset) getAssetStore().get(identifier);
if (asset == null) return null;
DS2 ds2 = (DS2) getEnvironment().getDelegationService();
RTRequest rtRequest = new RTRequest(getEnvironment().getClient(), null);
rtRequest.setAccessToken(asset.getAccessToken());
rtRequest.setRefreshToken(asset.getRefreshToken());
RTResponse rtResponse = ds2.refresh(rtRequest);
asset.setAccessToken(rtResponse.getAccessToken());
asset.setRefreshToken(rtResponse.getRefreshToken());
return asset;
}
public boolean isAccessTokenValid(String id) {
OA2Asset asset = getAsset2(id);
if (asset == null) {
throw new NoSuchAssetException("Error: the asset with identifier \"" + id + "\" was not found.");
}
try {
DateUtils.checkTimestamp(asset.getAccessToken().getToken(), 15 * 60 * 1000L);
} catch (Throwable t) {
return false;
}
return true;
}
public UserInfo getUserInfo(String identifier) {
OA2Asset asset = getAsset2(identifier);
if (asset == null || asset.getAccessToken() == null) return null;
UIRequest uiRequest = new UIRequest(asset.getAccessToken());
uiRequest.setClient(getEnvironment().getClient());
DS2 ds2 = (DS2) getEnvironment().getDelegationService();
UIResponse resp = ds2.getUserInfo(uiRequest);
JSONObject json = JSONObject.fromObject(resp.getRawJSON());
UserInfo ui = (UserInfo) JSONObject.toBean(json, UserInfo.class);
return ui;
}
protected OA2Asset getAsset2(String id) {
return (OA2Asset) getAssetStore().get(id);
}
/**
* Note that this requires the identifier, not a token.
*
* @param id
* @return
*/
public OA2Asset getCert(String id) {
OA2Asset OA2Asset = (OA2Asset) getAssetStore().get(id);
AssetResponse assetResponse = getCert(OA2Asset.getAccessToken().getToken(), null);
OA2Asset.setCertificates(assetResponse.getX509Certificates());
OA2Asset.setUsername(assetResponse.getUsername());
getAssetStore().save(OA2Asset);
return OA2Asset;
}
}