All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.uiuc.ncsa.myproxy.oauth2.tools.OA2TestCommands Maven / Gradle / Ivy

The newest version!
package edu.uiuc.ncsa.myproxy.oauth2.tools;

import edu.uiuc.ncsa.myproxy.oa4mp.client.AssetResponse;
import edu.uiuc.ncsa.myproxy.oa4mp.client.ClientEnvironment;
import edu.uiuc.ncsa.myproxy.oa4mp.client.OA4MPResponse;
import edu.uiuc.ncsa.myproxy.oa4mp.client.storage.AssetStoreUtil;
import edu.uiuc.ncsa.myproxy.oa4mp.server.testing.TestCommands;
import edu.uiuc.ncsa.oa4mp.oauth2.client.OA2Asset;
import edu.uiuc.ncsa.oa4mp.oauth2.client.OA2MPService;
import edu.uiuc.ncsa.security.core.Identifier;
import edu.uiuc.ncsa.security.core.util.DateUtils;
import edu.uiuc.ncsa.security.core.util.DebugUtil;
import edu.uiuc.ncsa.security.core.util.MyLoggingFacade;
import edu.uiuc.ncsa.security.delegation.client.request.RTResponse;
import edu.uiuc.ncsa.security.delegation.token.AuthorizationGrant;
import edu.uiuc.ncsa.security.delegation.token.impl.AuthorizationGrantImpl;
import edu.uiuc.ncsa.security.oauth_2_0.UserInfo;
import edu.uiuc.ncsa.security.oauth_2_0.client.ATResponse2;
import edu.uiuc.ncsa.security.util.cli.InputLine;
import edu.uiuc.ncsa.security.util.pkcs.CertUtil;
import net.sf.json.JSONObject;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.Date;
import java.util.HashMap;
import java.util.StringTokenizer;

import static edu.uiuc.ncsa.security.oauth_2_0.OA2Constants.ID_TOKEN;
import static edu.uiuc.ncsa.security.oauth_2_0.OA2Constants.RAW_ID_TOKEN;

/**
 * A command line client. Invoke help as needed, but the basic operation is to create the initial
 * request url using the {@link #geturi(InputLine)} call, paste it in your browser, authenticate
 * (since this is an OIDC client, you must pass through a browser at some point). The call back should
 * fail, so you copy the attempted callback from the service using the {@link #setgrant(InputLine)}
 * call. You can then do whatever you needed (get an access token, get refresh tokens if the server supports it)
 * inspect id tokens and such.
 * 

Created by Jeff Gaynor
* on 5/11/16 at 2:57 PM */ public class OA2TestCommands extends TestCommands { public OA2TestCommands(MyLoggingFacade logger, ClientEnvironment ce) { super(logger, ce); } protected OA2MPService service; protected OA2MPService getOA2S() { return (OA2MPService) getService(); } @Override public OA2MPService getService() { if (service == null) { service = new OA2MPService(getCe()); } return service; } public void getURIHelp() { say("Usage: This will create the correct URL to pass to your browser."); say(" This URL should be pasted exactly into the location bar."); say(" You must then authenticate. After you authenticate, the"); say(" service will attempt a call back to a client endpoint which will"); say(" fail (this is the hook that lets us do this manually)."); say(" Next Step: You should invoke setgrant with the callback uri from the server."); } SecureRandom secureRandom = new SecureRandom(); protected String getRandomString() { long ll = secureRandom.nextLong(); return Long.toHexString(ll); } /** * Constructs the URI * * @param inputLine * @throws Exception */ public void geturi(InputLine inputLine) throws Exception { if (showHelp(inputLine)) { getURIHelp(); return; } Identifier id = AssetStoreUtil.createID(); OA4MPResponse resp = getService().requestCert(id); DebugUtil.dbg(this, "client id = " + getCe().getClientId()); dummyAsset = (OA2Asset) getCe().getAssetStore().get(id.toString()); say(resp.getRedirect().toString()); } protected String createURI(String base, HashMap args) throws UnsupportedEncodingException { String uri = base; boolean firstPass = true; for (String key : args.keySet()) { String value = args.get(key); uri = uri + (firstPass ? "?" : "&") + key + "=" + encode(value); if (firstPass) firstPass = false; } canGetGrant = true; return uri; } static String encoding = "UTF-8"; String encode(String x) throws UnsupportedEncodingException { if (x == null) return ""; return URLEncoder.encode(x, encoding); } String decode(String x) throws UnsupportedEncodingException { if (x == null) return ""; return URLDecoder.decode(x, encoding); } AuthorizationGrant grant; public void setgrant(InputLine inputLine) throws Exception { if (inputLine.size() != 2 || showHelp(inputLine)) { setGrantHelp(); return; } String x = inputLine.getArg(1); // zero-th element is the name of this function. 1st is the actual argument. // now we parse this. if (!x.startsWith(getCe().getCallback().toString())) { say("The callback in the configuration does not match that in the argument you gave"); return; } String args = x.substring(x.indexOf("?") + 1); // skip the ? in the substring. StringTokenizer st = new StringTokenizer(args, "&"); while (st.hasMoreTokens()) { String current = st.nextToken(); if (current.startsWith("code=")) { URI uri = URI.create(decode(current.substring(5))); say("grant=" + uri.toString()); // length of string "code=" grant = new AuthorizationGrantImpl(uri); } } } public OA2Asset getDummyAsset() { return dummyAsset; } public void clear(InputLine inputLine) throws Exception { if (showHelp(inputLine)) { getClearHelp(); return; } dummyAsset = null; assetResponse = null; currentATResponse = null; grant = null; rawIdToken = null; claims = null; canGetCert = false; canGetGrant = false; canGetRT = false; canGetAT = false; } boolean canGetGrant = false; boolean canGetAT = false; boolean canGetCert = false; boolean canGetRT = false; protected void getClearHelp() { say("clear: reset all internal state and restart. You should do this rather than just starting over"); say(" as you may run into old state."); } OA2Asset dummyAsset; protected void saveCertHelp() { say("savecert filename"); say("This will save the cert (be sure to do a getcert call first so you have one) to the"); say("fully qualified filename"); say("If there is no cert available, no file will be written, but a message will be printed."); } /** * If the state supports this, it will save the current cert to a file. The complete filename must be supplied, * including any path. * * @param inputLine * @throws Exception */ public void savecert(InputLine inputLine) throws Exception { if (showHelp(inputLine)) { saveCertHelp(); return; } if (assetResponse == null) { say("Sorry, but there is no cert to save. Please do a successful getcert call first."); return; } String cert = CertUtil.toPEM(assetResponse.getX509Certificates()); if (!inputLine.hasArgs()) { say("Sorry. You did not specify a file so the cert cannot be saved."); return; } String fileName = inputLine.getArg(1); FileWriter fileWriter = new FileWriter(fileName); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write(cert + "\n"); bufferedWriter.flush(); bufferedWriter.close(); say("File \"" + fileName + "\" saved successfully."); } String rawIdToken = null; protected void showRawTokenHelp() { sayi("showRawToken - This will show the raw id token, i.e., the JWT. "); sayi(" If you wish to see the contents of this JWT"); sayi(" you should probably invoke showClaims instead."); } public void showrawtoken(InputLine inputLine) throws Exception { if (grant == null || showHelp(inputLine)) { getATHelp(); return; } if (rawIdToken == null) { sayi("No id token."); return; } if (rawIdToken.length() == 0) { sayi("Empty id token"); return; } sayi(rawIdToken); } JSONObject claims = null; public void showclaims(InputLine inputLine) throws Exception { if (grant == null || showHelp(inputLine)) { showClaimsHelp(); return; } if (claims == null || claims.isEmpty()) { say("(no claims found)"); } else { say(claims.toString(2)); } } protected void showClaimsHelp() { sayi("showClaims - This will show the most recent set of claims. You must get an access token"); sayi(" before this is set."); sayi(" You may also see the raw version of this (simply the JWT) by calling showRawToken."); } public void getat(InputLine inputLine) throws Exception { /* if(!canGetAT){ say("Sorry, but you have not gotten a grant yet here, so you cannot get an access token."); }*/ if (grant == null || showHelp(inputLine)) { getATHelp(); return; } DebugUtil.dbg(this, "Getting AT, grant=" + grant); currentATResponse = getOA2S().getAccessToken(getDummyAsset(), grant); Object x = currentATResponse.getParameters().get(RAW_ID_TOKEN); if (x == null) { x = ""; } else { rawIdToken = x.toString(); } claims = (JSONObject) currentATResponse.getParameters().get(ID_TOKEN); if (inputLine.hasArg(CLAIMS_FLAG)) { if (claims.isEmpty()) { say("(no claims found)"); } else { say(claims.toString(2)); } } printTokens(); } ATResponse2 currentATResponse; protected void getCertHelp() { say("getcert: This will get the requested cert chain from the server."); } protected void getUIHelp() { say("getuserinfo: This will get the user info from the server. You must have already authenticated"); say(" *and* gotten a valid access token by this point. Just a list of these it printed."); say(" What is returned is dependant upon what the server supports."); } public void getuserinfo(InputLine inputLine) throws Exception { if (showHelp(inputLine)) { getUIHelp(); return; } UserInfo userInfo = getOA2S().getUserInfo(dummyAsset.getIdentifier().toString()); say("user info:"); for (String key : userInfo.getMap().keySet()) { say(" " + key + " = " + userInfo.getMap().get(key)); } } AssetResponse assetResponse = null; public void getcert(InputLine inputLine) throws Exception { if (showHelp(inputLine)) { getCertHelp(); return; } assetResponse = getOA2S().getCert(dummyAsset, currentATResponse); if (assetResponse.getUsername() != null) { say("returned username=" + assetResponse.getUsername()); } say("X509Certs:"); say(CertUtil.toPEM(assetResponse.getX509Certificates())); } protected void getRTHelp() { say("getrt [-claims]:"); say(" Get a new refresh token. You must have already called getat to have gotten an access token"); say(" first. This will print out a summary of the expiration time."); say(" If the " + CLAIMS_FLAG + " flag is supplied, the id token will be printed"); } protected void printTokens() { if (dummyAsset.getAccessToken() != null) { say(" access token = " + dummyAsset.getAccessToken().getToken()); } if (dummyAsset.getRefreshToken() != null) { say("refresh token = " + dummyAsset.getRefreshToken().getToken()); say("RT expires in = " + dummyAsset.getRefreshToken().getExpiresIn() + " ms."); Date startDate = DateUtils.getDate(dummyAsset.getRefreshToken().getToken()); startDate.setTime(startDate.getTime() + dummyAsset.getRefreshToken().getExpiresIn()); say(" expires at " + startDate); } } public static final String CLAIMS_FLAG = "-claims"; public void getrt(InputLine inputLine) throws Exception { if (showHelp(inputLine)) { getRTHelp(); return; } RTResponse rtResponse = getOA2S().refresh(dummyAsset.getIdentifier().toString()); dummyAsset = (OA2Asset) getCe().getAssetStore().get(dummyAsset.getIdentifier().toString()); // Have to update the AT reponse here every time or no token state is preserved. currentATResponse = new ATResponse2(dummyAsset.getAccessToken(), dummyAsset.getRefreshToken()); currentATResponse.setParameters(rtResponse.getParameters()); JSONObject json = JSONObject.fromObject(currentATResponse.getParameters()); claims = json; if (inputLine.hasArg(CLAIMS_FLAG)) { if (json.isEmpty()) { say("(no claims found)"); } else { say(json.toString(2)); } } printTokens(); } protected void getATHelp() { say("getat [-claims]:"); say(" Gets the access token and refresh token (if supported on the server) for a given grant. "); say(" Your must have already set the grant with the setgrant call."); say(" A summary of the refresh token and its expiration is printed, if applicable."); say(" If the -" + CLAIMS_FLAG + " flag is supplied, the id token will be printed"); } protected void setGrantHelp() { say("setgrant: The assumption is that you use geturi to get the correct authorization uri and have "); say(" logged in. Your browser *should* have a call back to your client. Cut and paste that"); say(" as the argument to this call. This will return a string with the grant in it. You can use"); say(" that to get an access token."); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy