package utils; import com.sap.jam.api.security.SignatureUtil; import org.opensaml.xml.util.Base64; import java.net.Proxy; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URLEncoder; import java.security.PrivateKey; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import utils.JamConfig; import utils.JamNetworkManager; public class JamTokenManager { final static String API_ODATA_TOKEN = "/api/v1/auth/token"; private static JamTokenManager instance = new JamTokenManager(); Map<String, Map<String, String>> hostTokenHashMap = new HashMap<String, Map<String, String>>(); private JamTokenManager() { } public static JamTokenManager getInstance() { return instance; } public void setTokenFromConfig( JamConfig.ConfigInfo config, String memberEmail ) throws Exception { String token = getTokenForMember(config.host, config.proxy, memberEmail, config.clientId, config.clientSecret, config.grantType, config.samlConfig); System.out.println("\n"); JamNetworkManager.getInstance().SetOAuthToken(token); JamNetworkManager.getInstance().SetProxy(config.proxy); } public String retrieveFromOAuthToken(final String host, final Proxy proxy, final JamNetworkParam headerParam) throws UnsupportedEncodingException, MalformedURLException, IOException { final JamNetworkUrl url = new JamNetworkUrl(host + API_ODATA_TOKEN); System.out.println(" Retrieving oAuth via: " + url.toString()); final HttpURLConnection connection = JamNetworkManager.getInstance().createConnection(url.toString(), "POST", proxy); connection.setDoOutput(true); final String requestBody = headerParam.toString(); OutputStream output = null; try { output = connection.getOutputStream(); output.write(requestBody.getBytes("UTF-8")); } finally { if (output != null) { try { output.close(); } catch (final IOException e) { e.printStackTrace(); } } } final int responseCode = connection.getResponseCode(); System.out.println("\n HTTP response code: " + responseCode); InputStream is; if (connection.getResponseCode() >= 400) { is = connection.getErrorStream(); } else { is = connection.getInputStream(); } final StringBuilder result = new StringBuilder(); final BufferedReader in = new BufferedReader(new InputStreamReader(is)); String inputLine; while ((inputLine = in.readLine()) != null) { result.append(inputLine); } in.close(); final String resultString = result.toString(); System.out.println(" Response body: " + resultString); final String oauthToken = resultString.split("\"")[3]; System.out.println(" OAuthToken: " + oauthToken); return oauthToken; } // Get a token for a specific member using SAML Assertion info public String getTokenForMember( final String host, /* eg. https://abc.com */ final Proxy proxy, /* eg. proxy.corp */ final String userEmail /* eg. blue@cherry.com with password: password123*/, final String clientId, /* eg. eXvVdfco4Ih6ZlN5SWAu */ final String clientSecret, /* eg. gKWU2vwPnb8d3fLQFkJTkFiGPLcx26VvA3EXxeWT */ final String grantType, /* eg. client_credentials | urn:ietf:params:oauth:grant-type:saml2-bearer */ final JamConfig.SamlConfigInfo samlConfig) throws Exception { // Source JAM => Get Access token from Source JAM final String urlString = host + API_ODATA_TOKEN; System.out.println(" Member[" + userEmail + "] Token => URL: " + urlString); // If token hashMap does not exist yet for the current host, create it if (!hostTokenHashMap.containsKey(host)) { final Map<String, String> tokenMap = new HashMap<String, String>(); hostTokenHashMap.put(host, tokenMap); } // Check if token exist in Hash map, if so return it or make the url request with SAML assertion to retrieve it final Map<String, String> tokens = hostTokenHashMap.get(host); if (tokens.containsKey(userEmail)) { final String tokenString = tokens.get(userEmail); System.out.print(" Retrieving oAuth via cache: " + tokenString); return tokens.get(userEmail); } // Set up header for getting token final JamNetworkParam param = new JamNetworkParam(); //param.add("grant_type", URLEncoder.encode(JamConfig.getInstance().getFromGrantType(), "UTF-8")); param.add("client_id", URLEncoder.encode(clientId, "UTF-8")); param.add("client_secret", URLEncoder.encode(clientSecret, "UTF-8")); param.add("grant_type", URLEncoder.encode(grantType, "UTF-8")); if (samlConfig != null && samlConfig.idpId != null) { final PrivateKey IDPPrivateKey = SignatureUtil.makePrivateKey(samlConfig.idpPrivateKey); // Set up attributes and assertion Map<String, List<Object>> attributes = null; attributes = new HashMap<String, List<Object>>(); attributes.put("client_id", Collections.singletonList((Object)clientId)); // Generate an assertion for a particular user final String samlAssertion = JamNetworkManager.getInstance().buildSignedSAML2Assertion(samlConfig.idpId, urlString, userEmail, "email", null, IDPPrivateKey, null, samlConfig.spId, attributes); System.out.println(" assertion:" + samlAssertion); String base64SamlAssertion = new String(Base64.encodeBytes(samlAssertion.getBytes(), Base64.DONT_BREAK_LINES)); param.add("assertion", URLEncoder.encode(base64SamlAssertion, "UTF-8")); } // Get Token from URL request final String tokenString = retrieveFromOAuthToken(host, proxy, param); // Store the token in our token hash map cache for this host url call if (tokenString != null) { tokens.put(userEmail, tokenString); } return tokenString; } }