Skip to content
Snippets Groups Projects
ObtainToken.java 8.43 KiB
Newer Older
  • Learn to ignore specific revisions
  • package code;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.URI;
    import java.net.URL;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.ArrayList;
    
    import java.util.List;
    
    import javax.net.ssl.HttpsURLConnection;
    
    import org.apache.commons.codec.binary.Base64;
    
    import com.sun.net.httpserver.HttpExchange;
    import com.sun.net.httpserver.HttpHandler;
    
    public class ObtainToken implements HttpHandler{
    	
    	private KeyCloak kcs;
    	private String state;
    	private String codeVerifier;
    	
    	public ObtainToken(KeyCloak kcs) {
    		this.kcs = kcs;
    	}
    
    	@Override
        public void handle(HttpExchange exchange) throws IOException {
            URI requestURI = exchange.getRequestURI();
            String stringURI = requestURI.toString();
            boolean wantsRedirectPage = Helper.compareText(stringURI,URI.create("/").toString());
            boolean wantsToken = Helper.compareText(stringURI,URI.create("/secured").toString()); 
            if(wantsToken)
            System.out.println("URI  = "+exchange.getRequestURI().getPath());
            
            if(!wantsRedirectPage && !wantsToken) {
                String error = "Invalid URI";
                OutputStream os = exchange.getResponseBody();
                exchange.sendResponseHeaders(400, error.getBytes().length);
                os.write(error.getBytes());
                os.close();
                return;
            }
    
            String requestMethod = exchange.getRequestMethod(); 
            if (Helper.compareText(requestMethod, "GET")) {
            	if(wantsRedirectPage) {
    	        	codeVerifier = createRandomString();
    	        	try {
    					String codeChallenge = createCodeChallenge(codeVerifier);
    					
    					state = createRandomString(); //An opaque arbitrary alphanumeric string your app adds to the initial request that Auth0 includes when redirecting back to your application. 
    					String nonce = "a81e1a84-8885-4702-b8d1-f6c5a0d1fc4d";
    //					System.out.println("CODE VERIFIER = "+codeVerifier);
    					// get the html page
    		            List<String> strlist = new ArrayList<>();
    		            String response = null;
    		            response = getRedirectPage();
    		            strlist.add("text/html");
    		            
    		            if(response != null && !Helper.compareText(response, "fail")){
    		            	response = response.replace("$DOMAIN", kcs.authServer())
    		            			.replace("$REALM", kcs.realm())
    		            			.replace("$MY_CODE_CHALLENGE", codeChallenge)
    		            			.replace("$MY_CLIENT_ID", kcs.clientId())
    		            			.replace("$MY_REDIRECT_URI", kcs.redirectUri())
    		            			.replace("$MY_NONCE",nonce)
    		            			.replace("$MY_STATE", state);	            	
    		        
    		                exchange.getResponseHeaders().put("content-type", strlist);
    		                exchange.sendResponseHeaders(200, response.getBytes().length);
    		                OutputStream os = exchange.getResponseBody();
    		                os.write(response.getBytes());
    		                os.close();
    		            } else {
    		                exchange.sendResponseHeaders(500, response.getBytes().length);
    		                OutputStream os = exchange.getResponseBody();
    		                os.write(response.getBytes());
    		                os.close();
    		            }
    				} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
    					System.out.println("Error during creation of code challenge");
    				}  
            	}
            	if(wantsToken) { 
            		// NON FUNZIONA PERCHE' LA 
            		String[] arr = stringURI.split("/secured");
            		for(int i=0; i<arr.length; i++)
            			System.out.println(arr[i]);
            		System.out.println("lunghezza = "+arr.length);
            		
            		String allParamsString = stringURI.split("/secured")[1];
            		System.out.println("allParamsString = "+allParamsString);
            		String[] allParamsArray = allParamsString.split("&");
            		String state = allParamsArray[0];
            		if(!this.state.equals(state)) {
            			Helper.badRequest(exchange);
            			return;
            		}
            		String authCode = allParamsArray[2];
            		
            		// request token  
            		String httpsURL = "http://"+kcs.authServer()+"/realms/"+kcs.realm()+"/protocol/openid-connect/token";
            		URL myUrl = new URL(httpsURL);
    //                SSLUtilities.trustAllHttpsCertificates();
    //                SSLUtilities.trustAllHostnames();
                    HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
    
                    conn.setReadTimeout(7000);
                    conn.setConnectTimeout(7000);
                    conn.setRequestMethod("POST");
                    conn.setDoOutput(true);
                    conn.setDoInput(true);
                    
                    conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
                 
                    String body = "grant_type=authorization_code"
                    		+ "&client_id="+kcs.clientId()
                    		+ "&code_verifier="+codeVerifier
                    		+ "&code="+authCode
                    		+ "&redirect_uri=https://localhost:3000/secured";
                    OutputStream outputStream = conn.getOutputStream();
                    outputStream.write(body.getBytes("UTF-8"));
                    outputStream.close();
    
                    String inputLine;
                    InputStream is = conn.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    String response = "";
                    while ((inputLine = br.readLine()) != null) {
                    	response += inputLine;
                    }
    
                    br.close();
                    System.out.println(response);
    //        	String answer = response.replace(remoteHOST,localHOST);
            		
            	}
            } else {
                Helper.methodNotAllowed(exchange);
            }
        }
    
        
    
    	private static String getRedirectPage() {
            String line;
            String page = Server.CLIENT_PATH+"/redirect.html";
    
            StringBuilder answer = new StringBuilder();
            if (getExtension(page).length() == 0)
                page += ".html";
    
            BufferedReader bufferedReader = null;
            try {
                FileReader fileReader = new FileReader(page);
    
                bufferedReader = new BufferedReader(fileReader);
                boolean isComment = false;
                while ((line = bufferedReader.readLine()) != null) {
                	line = line.trim();
    
                	if(line.startsWith("<!--") && line.endsWith("-->")) {
                		continue;
                	}
                	if(line.startsWith("<!--")) {
                		isComment = true;
                		continue;
                	}
                	if(line.endsWith("-->")) {
                		isComment = false;
                		continue;
                	}
    
                	if(!isComment && line.length()>0)
                    	answer.append(line).append("\n");
                }
            } catch (FileNotFoundException ex) {
                System.out.println("Unable to open file '" + page + "'");
                return "fail";
            } catch (IOException ex) {
                System.out.println("Error reading file '" + page + "'");
                return "fail";
            } finally {
                try{
                    if(bufferedReader != null)
                        bufferedReader.close();
                } catch (IOException ex){
                    System.out.println("Error closing bufferedReader");
                }
            }
            return answer.toString();
        }
    
    
        private static String getExtension(String file) {
            int i = file.length() - 1;
            while (i > 0 && file.charAt(i) != '.' && file.charAt(i) != '/')
                i--;
            if (file.charAt(i) == '.')
                return file.substring(i + 1);
            else
                return "";
        }
        
        
        private String createRandomString() {
        	SecureRandom sr = new SecureRandom();
        	byte[] code = new byte[32];
        	sr.nextBytes(code); 
        	return java.util.Base64.getUrlEncoder().withoutPadding().encodeToString(code);
        }
        
        
        private String createCodeChallenge(String verifier) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        	byte[] bytes = verifier.getBytes("US-ASCII");
        	MessageDigest md = MessageDigest.getInstance("SHA-256");
        	md.update(bytes, 0, bytes.length);
        	byte[] digest = md.digest();
        	return Base64.encodeBase64URLSafeString(digest);
    	}
    
    }