Skip to content

Instantly share code, notes, and snippets.

@shimondoodkin
Last active January 19, 2021 01:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shimondoodkin/647c3fdcea34c22ff5e0e338c13636b0 to your computer and use it in GitHub Desktop.
Save shimondoodkin/647c3fdcea34c22ff5e0e338c13636b0 to your computer and use it in GitHub Desktop.
should be good for java 1.6
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