Last active
January 19, 2021 01:52
-
-
Save shimondoodkin/647c3fdcea34c22ff5e0e338c13636b0 to your computer and use it in GitHub Desktop.
should be good for java 1.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package open_id_raw_request_token; | |
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.URL; | |
import java.net.URLEncoder; | |
import java.nio.charset.StandardCharsets; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.Map; | |
import java.util.StringJoiner; | |
import org.json.simple.JSONObject; | |
import org.json.simple.JSONValue; | |
public class OpenIdRawRequestToken { | |
private static String HttpGET_AcceptsJSON_CheckHTTPS(String uri ) throws MalformedURLException, Exception, IOException, NullPointerException { | |
URL url = new URL(uri); | |
if(!url.getProtocol().equals("https")) | |
throw new Exception("OpenIdRawRequestToken - not https "+uri); | |
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // Open a connection(?) on the URL(??) and cast the response(???) | |
connection.setRequestProperty("accept", "application/json"); // Now it's "open", we can set the request method, headers etc. | |
String strjson=HttpURLConnection_GetResponseBody(connection); | |
return strjson; | |
} | |
private static String queryString(HashMap<String, String> PostFormValues) throws UnsupportedEncodingException { | |
StringJoiner sj = new StringJoiner("&"); | |
for(Map.Entry<String,String> entry : PostFormValues.entrySet()) | |
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" | |
+ URLEncoder.encode(entry.getValue(), "UTF-8")); | |
String qs=sj.toString(); | |
return qs; | |
} | |
private static String HttpPOST_String_AcceptsJSON_CheckHTTPS(String uri,String PostData,String PostContentType) throws MalformedURLException, Exception, IOException, NullPointerException { | |
URL url = new URL(uri); | |
if(!url.getProtocol().equals("https")) | |
throw new Exception("OpenIdRawRequestToken - not https "+uri); | |
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // Open a connection(?) on the URL(??) and cast the response(???) | |
connection.setRequestProperty("accept", "application/json"); // Now it's "open", we can set the request method, headers etc. | |
connection.setRequestMethod("POST"); // PUT is another valid option | |
connection.setDoOutput(true); | |
byte[] out = PostData.getBytes(StandardCharsets.UTF_8); | |
int length = out.length; | |
connection.setFixedLengthStreamingMode(length); | |
connection.setRequestProperty("Content-Type", PostContentType); | |
connection.connect(); | |
OutputStream os = connection.getOutputStream(); | |
os.write(out); | |
String strjson=HttpURLConnection_GetResponseBody(connection); | |
return strjson; | |
} | |
private static String HttpPOST_Form_AcceptsJSON_CheckHTTPS(String uri,HashMap<String, String> PostFormValues) throws MalformedURLException, Exception, IOException,NullPointerException { | |
return HttpPOST_String_AcceptsJSON_CheckHTTPS( uri,queryString(PostFormValues),"application/x-www-form-urlencoded; charset=UTF-8"); | |
} | |
private static String HttpURLConnection_GetResponseBody(HttpURLConnection connection) throws IOException, NullPointerException | |
{ | |
if (100 <= connection.getResponseCode() && connection.getResponseCode() <= 399) { | |
return convertInputStreamToString(connection.getInputStream()); | |
} else { | |
return convertInputStreamToString(connection.getErrorStream()); | |
} | |
} | |
private static String convertInputStreamToString(InputStream is) throws IOException { | |
BufferedReader br = new BufferedReader(new InputStreamReader(is));; | |
StringBuilder sb=new StringBuilder(); | |
String line; | |
while ((line = br.readLine()) != null) { | |
sb.append(line); | |
} | |
return sb.toString(); | |
} | |
public static Token get_OpenId_Berer_Token(String OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash, String scope, String client_id, String client_secret ) | |
throws Exception | |
{ | |
try { | |
JSONObject DiscoveryEndpoint_JSON = get_OpenId_Discovery(OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash); | |
String url_token_endpoint=(String) DiscoveryEndpoint_JSON.get("token_endpoint"); | |
return openId_Request_BererToken(url_token_endpoint, scope, client_id, client_secret ); | |
} catch (MalformedURLException e) { | |
//e.printStackTrace(); | |
throw new Exception("get_OpoenId_Berer_Token - MalformedURLException",e); | |
} catch (IOException e) { | |
//e.printStackTrace(); | |
throw new Exception("get_OpoenId_Berer_Token - IOException",e); | |
} | |
} | |
private static Token openId_Request_BererToken(String url_token_endpoint, String scope, String client_id, String client_secret ) | |
throws MalformedURLException, Exception, IOException, NullPointerException { | |
HashMap<String, String> PostValues=new HashMap<String, String>(); | |
PostValues.put("grant_type", "client_credentials"); | |
PostValues.put("scope", scope); | |
PostValues.put("client_id", client_id); | |
PostValues.put("client_secret", client_secret); | |
final JSONObject TokenEndpoint_JSON=(JSONObject) JSONValue.parse(HttpPOST_Form_AcceptsJSON_CheckHTTPS(url_token_endpoint,PostValues)); | |
@SuppressWarnings("unchecked") | |
String error=(String) TokenEndpoint_JSON.getOrDefault("error", ""); | |
if(!error.isEmpty()) | |
throw new Error("OpenIdRawRequestToken - token request error "+error); | |
Token token =new Token(); | |
token.access_token=(String)TokenEndpoint_JSON.get("access_token"); | |
token.expires_in=((Long)TokenEndpoint_JSON.get("expires_in")).intValue(); | |
token.token_type=(String)TokenEndpoint_JSON.get("token_type"); | |
token.scope=(String)TokenEndpoint_JSON.get("scope"); | |
token.date=System.currentTimeMillis(); | |
token.dateExpiers=(System.currentTimeMillis()+(token.expires_in*1000))-60000; | |
return token; | |
} | |
public static class Token { | |
public long dateExpiers; | |
public long date; | |
public String access_token; | |
public int expires_in; | |
public String token_type; | |
public String scope; | |
boolean failed=false; | |
public boolean isExpierd() { | |
return System.currentTimeMillis()>dateExpiers; | |
} | |
public boolean isFailed() { | |
return failed; | |
} | |
public void Failed() { | |
failed=true; | |
} | |
} | |
private static JSONObject get_OpenId_Discovery(String OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash) | |
throws MalformedURLException, Exception, IOException, NullPointerException { | |
JSONObject DiscoveryEndpoint_JSON; | |
final String DiscoveryEndpoint_Authority = OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash ; | |
String openid_default_discovery_endpoint_suffix = "/.well-known/openid-configuration"; | |
String DiscoveryEndpoint_Url = DiscoveryEndpoint_Authority + openid_default_discovery_endpoint_suffix ; | |
DiscoveryEndpoint_JSON = (JSONObject) JSONValue.parse(HttpGET_AcceptsJSON_CheckHTTPS(DiscoveryEndpoint_Url)); | |
OpenId_Discovery_doSomeValidations(DiscoveryEndpoint_JSON,DiscoveryEndpoint_Authority); | |
return DiscoveryEndpoint_JSON; | |
} | |
private static void OpenId_Discovery_doSomeValidations(JSONObject DiscoveryEndpoint_JSON,String DiscoveryEndpoint_Authority ) throws Exception, MalformedURLException { | |
// do some validations before returning endpoint | |
@SuppressWarnings("unchecked") | |
String issuer=(String) DiscoveryEndpoint_JSON.getOrDefault("issuer", "" ) ; | |
if( !issuer.equals(DiscoveryEndpoint_Authority)) | |
throw new Exception("get_OpoenId_Berer_Token issuer error "+issuer + " != "+ DiscoveryEndpoint_Authority); | |
ValidateEndpoints(DiscoveryEndpoint_JSON, | |
asArrayList(new URL(DiscoveryEndpoint_Authority).getAuthority()), | |
new ArrayList<String>(), | |
false ); | |
} | |
private static ArrayList<String> asArrayList(String ...args){ | |
ArrayList<String> list=new ArrayList<String>(); | |
for(final String el : args) | |
list.add(el); | |
return list; | |
} | |
private static void ValidateEndpoints(JSONObject json, ArrayList<String> allowedAuthorities, ArrayList<String> EndpointValidationExcludeList, boolean RequireKeySet) throws MalformedURLException ,Exception | |
{ | |
String OidcConstants_Discovery_JwksUri = "jwks_uri"; | |
String OidcConstants_Discovery_CheckSessionIframe = "check_session_iframe"; | |
@SuppressWarnings("rawtypes") | |
Iterator it = json.entrySet().iterator(); | |
while (it.hasNext()) { | |
@SuppressWarnings("rawtypes") | |
Map.Entry pair = (Map.Entry)it.next(); | |
String key=((String) pair.getKey()).toLowerCase(); | |
if (key.endsWith("endpoint") || | |
key.equals(OidcConstants_Discovery_JwksUri) || | |
key.equals(OidcConstants_Discovery_CheckSessionIframe)) | |
{ | |
String endpoint = (String) pair.getValue(); | |
// if endpoint is on exclude list, don't validate | |
if (EndpointValidationExcludeList.contains(key)) | |
{ | |
continue; | |
} | |
URL uri = new URL(endpoint); // throws if invalid url | |
if (!uri.getProtocol().equals("https")) | |
{ | |
throw new Exception("OpenIdRawRequestToken - Malformed endpoint url from discovery: "+key+" not https url "+endpoint); | |
} | |
boolean isAllowed = false; | |
for(String host : allowedAuthorities) | |
{ | |
if (host.equals(uri.getAuthority())) | |
{ | |
isAllowed = true; | |
} | |
} | |
if (!isAllowed) | |
{ | |
throw new Exception("OpenIdRawRequestToken - an Endpoint has a different host than authority: "+key+" not https url "+endpoint); | |
} | |
} | |
} | |
if (RequireKeySet) | |
{ | |
@SuppressWarnings("unchecked") | |
String JwksUri=(String) json.getOrDefault(OidcConstants_Discovery_JwksUri, ""); | |
if (JwksUri.isEmpty()) | |
{ | |
throw new Exception("OpenIdRawRequestToken - KeySet endpoint is missing"); | |
} | |
} | |
} | |
public static HashMap<String,Token> TokenCache=new HashMap<String, Token>(); | |
public static Token get_OpenId_Berer_Token_cached(String OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash, String scope, String client_id, String client_secret )throws Exception | |
{ | |
final String key=OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash; | |
if(TokenCache.containsKey(key)) | |
{ | |
Token token=TokenCache.get(key); | |
if(token.isExpierd()||token.isFailed()) | |
TokenCache.remove(key); | |
else | |
return token; | |
} | |
Token token = get_OpenId_Berer_Token( OpenId_DiscoveryEndpoint_Authority_Url_base_url_without_trailing_slash, scope, client_id, client_secret ); | |
TokenCache.put(key,token); | |
return token; | |
} | |
public static void main(String[] args) { | |
//example: | |
Token token=null; | |
try { | |
token=get_OpenId_Berer_Token_cached( | |
"https://identity.server.com", | |
"myscope", | |
"myid", | |
"mysecret" | |
); | |
System.out.println(token.access_token); | |
URL url = new URL("https://api.server.com"); | |
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); | |
connection.setRequestProperty("Authorization", "Bearer "+token.access_token); | |
connection.setRequestProperty("accept", "application/json"); | |
String strjson=HttpURLConnection_GetResponseBody(connection); | |
System.out.println(strjson); | |
}catch(Exception e) { | |
if(token!=null) token.Failed(); | |
e.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment