How to build an OAuth authentication system

OAuth.java

The purpose of this class is to serve as an example of how to build your own OAuth authentication system. In our case, we have created an "attempAuthentication" method. This method checks if the request contains the "code" parameter. If it doesn't the "getOAuthCode" method will be called. Otherwise, it will try to get the access token using the "getOAuthToken" method.

You will have to create the procedures to send the necessary parameters (request_uri, client_id, client_secret...). In our example, we assume that we can get all of them as request parameters or attributes.

Finally, if you are in the "getOAuthToken" step you will have to make a post request using a "HttpClient" instance, as you can see in the example.

package com.proton.developers;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;

import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;

public class OAuth {
	
	private static String AUTHORIZATION_ENDPOINT	= "/external/oauth/authorize";
	private static String TOKEN_ENDPOINT			= "/external/oauth/token";
	private static String PROTON_URL				= "https://proton.prot-on.com";
	
	/**
	 * Calls getOAuthCode if code parameter does not exist. Otherwise calls getOAuthToken.
	 * @param  request
	 * @param  response
	 * @throws  IOException
	 * @return  String
	 */
	public static String attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		String auth = null;
		if (request.getParameter("code") == null) {
			String redirect = getOAuthCode(request, response);
	    	response.sendRedirect(redirect);
	    	return null;
		} else {
			String oauthToken = getOAuthToken(request);
			auth = oauthToken;
		}
        
        return auth;
	}
	
	/**
	 * Gets an OAuth Authorization Code redirecting to Proton Authorization Endpoint
	 * @param  request
	 * @param  response
	 * @throws  MalformedURLException
	 * @throws  IOException
	 * @return  String
	 */
	private static String getOAuthCode(HttpServletRequest request,
			HttpServletResponse response) throws MalformedURLException, IOException{
		String redirect = null;
		URIBuilder builder = null;
		try {
			builder = new URIBuilder(PROTON_URL + AUTHORIZATION_ENDPOINT);
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		
		String redirect_url = request.getAttribute("redirect_url")!=null ? request.getAttribute("redirect_url").toString() : request.getRequestURL().toString();
    	builder.addParameter("response_type", "code")
    		.addParameter("client_id", request.getParameter("client_id").toString())
    		.addParameter("redirect_uri", redirect_url);
    	
    	redirect = builder.toString();
    	
    	return redirect;
	}
	
	/**
	 * Gets an OAuth Access Token
	 * @param  request
	 * @throws  JsonParseException
	 * @throws  JsonMappingException
	 * @throws  IllegalStateException
	 * @throws  IOException
	 * @return  String
	 */
	private static String getOAuthToken(HttpServletRequest request) throws JsonParseException, JsonMappingException, IllegalStateException, IOException{
		
		List nameValuePairs = new ArrayList();
		nameValuePairs.add(new BasicNameValuePair("code", request.getParameter("code")));
		nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
		nameValuePairs.add(new BasicNameValuePair("redirect_uri", request.getRequestURL().toString()));
		
		HttpResponse oauthResponse =  makePostRequest((PROTON_URL + TOKEN_ENDPOINT), request.getAttribute("client_id").toString(), request.getAttribute("client_secret").toString(), nameValuePairs);
		
		String token = IOUtils.toString(oauthResponse.getEntity().getContent());
		
		return token;
	}
	
	/**
	 * Executes the authentication request to get the OAuth Access Token
	 * @param  uri
	 * @param  client_id
	 * @param  client_secret
	 * @param  nameValuePairs
	 * @return  HttpResponse
	 */
	public static HttpResponse makePostRequest(String uri, String client_id, String client_secret, List nameValuePairs){
        try {       
            String encoding = new String(Base64.encodeBase64((client_id + ":" + client_secret).getBytes()));
            
            HttpPost post = new HttpPost(uri);
            post.setHeader("Authorization", "Basic " + encoding);
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            
            
            HttpClient client = HttpClients
            		.custom()
            		.build(); 
            
            return client.execute(post);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}