OAuth2.0 Implementation for Google API in JAVA or PHP

Using OAuth2.0 authenticating your web application with Google API is now very easy. This will help your applications to maintain sing user repository from Google logging, and no need to maintain any password at your application side.  Here the idea is to give an idea of complete Web Server flow (Oauth2 web server side dance) and understand it completely with complete open source technologies. Steps involved for this process are given below:

First step is go to Google API Console and register a project then create a Web Application userid and secret key.  (Make sure that the registering URL will have your application’s context path).

Note: Modify the userid/secretkeys as per your settings.

Create a web project ( say TestProject) and then create a servlet as shown below:

package com.test.oauth;

import java.io.BufferedReader;
import java.io.IOException;

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

import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.io.IOUtils;

public class OAuthTwoCallBackServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

private static String client_id = “895498929378-4uohdps8sb5v6jp8saf0rea73c0h87nr.apps.googleusercontent.com”;
private static String client_secret = “LsIy_r4-S22jGwGJkbNeYQ1H”;
private static String redirectURL = “http://localhost:8080/TestProject/callback”;
private String auth_code = null;

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {

System.out.println(“Callback to URI that is configured in Google API Console”);
resp.setContentType(“text/html”);
resp.getWriter().println(” “);
resp.getWriter().println(” “);
resp.getWriter().println(”
Top of Form

“);

Bottom of Form

if (req.getParameter(“code”) == null) {

if (req.getParameter(“error”) != null) {
resp.getWriter().println(“Hello, ” + req.getParameter(“error”));
} else {

resp.getWriter().println(“”);
resp.getWriter().println(“”);
resp.getWriter().println(”

“);    resp.getWriter().println(“”);
resp.getWriter().println(”

Hello

“);
resp.getWriter().println(“To login with Google Account click here “);
resp.getWriter().println(“”);
resp.getWriter().println(”    resp.getWriter().println(” alt=’Powered by Google App Engine’ />”);
resp.getWriter().println(”
“);    resp.getWriter().println(”
“);       }
} else {
resp.getWriter().println(”

Code

“);
resp.getWriter().println(“Authentication Code = ” + req.getParameter(“code”));
this.auth_code = req.getParameter(“code”);

// Exchange the code for token
HttpClient httpclient = new HttpClient();
BufferedReader bufferedreader = null;
PostMethod postmethod = new PostMethod(
“https://accounts.google.com/o/oauth2/token”);
postmethod.addParameter(“code”, auth_code);
postmethod.addParameter(“client_id”, client_id);
postmethod.addParameter(“client_secret”, client_secret);
postmethod.addParameter(“redirect_uri”, redirectURL);
postmethod.addParameter(“grant_type”, “authorization_code”);
String access_token = null;
String token_type = null;
int expires_in = 0;
String id_token = null;
try {

int rCode = httpclient.executeMethod(postmethod);
System.out.println(“HTTP POST for Token rCode is” + rCode);

if (rCode == HttpStatus.SC_NOT_IMPLEMENTED) {
System.err.println(“The Post postmethod is not implemented by this URI”);
postmethod.getResponseBodyAsString();
} else if (rCode == HttpStatus.SC_NOT_ACCEPTABLE) {
System.out.println(postmethod.getResponseBodyAsString());
} else {

String jsonTxt = IOUtils.toString(postmethod
.getResponseBodyAsStream());

JSONObject json = (JSONObject) JSONSerializer
.toJSON(jsonTxt);

access_token = json.getString(“access_token”);
token_type = json.getString(“token_type”);
expires_in = json.getInt(“expires_in”);
id_token = json.getString(“id_token”);
System.out.println(“======== TOKEN INFO ========”);
System.out.println(“access_token: ” + access_token);
System.out.println(“token_type: ” + token_type);
System.out.println(“expires_in: ” + expires_in);
System.out.println(“id_token: ” + id_token);
System.out.println(“=========================”);
resp.getWriter().println(”

Token & Refresh

“);
resp.getWriter().println(“Access Token = ” + access_token);
resp.getWriter().println(“Refresh Token = ” + id_token);
resp.getWriter().println(“Expire Time (Seconds) = ” + expires_in);
resp.getWriter().println(“Token Type = ” + token_type);
}
} catch (Exception e) {
System.err.println(e);
} finally {
postmethod.releaseConnection();
if (bufferedreader != null)
try {
bufferedreader.close();
} catch (Exception fe) {
fe.printStackTrace();
}
}

//Calling Google account info API
User user = null;
httpclient = new HttpClient();
bufferedreader = null;
GetMethod getmethod = new GetMethod(“https://www.googleapis.com/oauth2/v1/userinfo?access_token=” + access_token);
try {
int rCode = httpclient.executeMethod(getmethod);
System.out.println(“HTTP GET for User rCode is” + rCode);

if (rCode == HttpStatus.SC_NOT_IMPLEMENTED) {
System.err
.println(“The Get method is not implemented by this URI”);
getmethod.getResponseBodyAsString();
} else if (rCode == HttpStatus.SC_NOT_ACCEPTABLE) {
System.out.println(getmethod.getResponseBodyAsString());
} else {

String jsonTxt = IOUtils.toString(getmethod
.getResponseBodyAsStream());
JSONObject json = (JSONObject) JSONSerializer
.toJSON(jsonTxt);

user = new User();
user.id = json.getString(“id”);
user.name = json.getString(“name”);
user.email = json.getString(“email”);
user.picture = json.getString(“picture”);
user.gender = json.getString(“gender”);
user.locale = json.getString(“locale”);

System.out.println(“============ TOKEN INFO ===============”);
System.out.println(“id: ” + user.id);
System.out.println(“name: ” + user.name);
System.out.println(“Gender: ” + user.gender);
System.out.println(“email: ” + user.email);
System.out.println(“pictureURL: ” + user.picture);
System.out.println(“Locale: ” + user.locale);
System.out.println(“====================================”);
}
} catch (Exception e) {
System.err.println(e);
} finally {
postmethod.releaseConnection();
if (bufferedreader != null)
try {
bufferedreader.close();
} catch (Exception fe) {
fe.printStackTrace();
}
}

// Get User Information
//resp.setContentType(“text/html”);
resp.getWriter().println(”

User Information

“);
resp.getWriter().println(”
“);

Property Data

resp.getWriter().println(”
Id
” + user.getId()+ ”
“);
resp.getWriter().println(”
Name
” + user.getName()+ ”
“);
resp.getWriter().println(”
Email
” + user.getEmail()+ ”
“);
resp.getWriter().println(”
Gender
” + user.getGender()+ ”
“);
resp.getWriter().println(”
Image

“);
resp.getWriter().println(”
Locale
” + user.getLocale()+ ”
“);
resp.getWriter().println(”
“);
}
}

public class User {
public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPicture() {
return picture;
}

public void setPicture(String picture) {
this.picture = picture;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public String getLocale() {
return locale;
}

public void setLocale(String locale) {
this.locale = locale;
}

String id;
String email;
String name;
String picture;
String gender;
String locale;

@Override
public String toString() {
return String.format(“id:%s,name:%s,email:%s,gender:%d,locale:%s”,
id, name, email, gender, locale);
}
}

public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
System.out.println(“This is never called”);
}
}

The web.xml file should have the following as well.

TestProject

ServletName:  OAuth2Callback

Servlet calssname: com.test.oauth.OAuthTwoCallBackServlet

Servlet Mapping:  OAuth2Callback

Servlet Mapping Name  /callback
Similarly for PHP I have create a Test project and Home.php file where nothing else is required.
The Home.php:

if(!isset($_GET[“code”]) || $_GET[“code”] ==””){

?>

Please click on Login button to lonon Google Apps using OAuth2.0 and get the Google Aaacount Details

}else{

$userProfile = array(
‘id’ => ”,
‘name’ => ”,
‘gender’ => ”,
’email’ => ”,
‘picture’ => ”,
‘locale’ => ”
);

$userProfile = authValidateUser($_GET[“code”]);

if(isset($userProfile[“email”]) && $userProfile[“email”] != “”){
?>

User Property Data

Name
Email
Gender
ID
Picture
Locale

}else{

?>

Unable to get User Data, Please try Again !!!

}

}

function authValidateUser($code)
{
$OAuth = array(
‘oauth_uri’ => ‘https://accounts.google.com/o/oauth2/auth’,
‘client_id’ => ‘284443344502-do31sm7eo7nogdcn5m0dmlgb0841r8j2.apps.googleusercontent.com’,
‘client_secret’ => ‘abUpKB-rqoBOx0DJv2fhJ44S’,
‘redirect_uri’ => ‘http://localhost/Test/Home.php’,
‘oauth_token_uri’ => ‘https://accounts.google.com/o/oauth2/token’
);

$token = array(
‘access_token’ => ”,
‘token_type’ => ”,
‘expires_in’ => ”,
‘refresh_token’ => ”
);

$userinfo = array(
‘id’ => ”,
‘name’ => ”,
‘gender’ => ”,
’email’ => ”,
‘picture’ => ”,
‘locale’ => ”
);

if(isset($code) && $code != “”){

// now exchange Authorization code for access token and refresh token
$token_response = _get_auth_token($OAuth, $code);
$json_obj = json_decode($token_response);
$token[“access_token”] = $json_obj->access_token;
$token[“token_type”] = $json_obj->token_type;
$token[“expires_in”] = $json_obj->expires_in;
$token[“refresh_token”] = $json_obj->refresh_token;
}

if(isset($token[“access_token”]) && $token[“access_token”] != “”){
//Exchange Authorization code for access token and refresh token
$userinfo_response = _get_user_info($token[“access_token”]);
$json_obj = json_decode($userinfo_response);
$userinfo[“id”] = $json_obj->id;
$userinfo[“name”] = $json_obj->name;
$userinfo[“gender”] = $json_obj->gender;
$userinfo[“email”] = $json_obj->email;
$userinfo[“picture”] = $json_obj->picture;
$userinfo[“locale”] = $json_obj->locale;
}

return $userinfo;
}

function _get_auth_token($params, $code)
{
$url = $params[‘oauth_token_uri’];

$fields = array(
‘code’ => $code,
‘client_id’ => $params[‘client_id’],
‘client_secret’ => $params[‘client_secret’],
‘redirect_uri’ => $params[‘redirect_uri’],
‘grant_type’ => ‘authorization_code’
);

$response = _do_post($url, $fields);
return $response;
}

function _get_refresh_token($params, $code)
{
$url = $params[‘oauth_token_uri’];

$fields = array(
‘code’ => $code,
‘client_id’ => $params[‘client_id’],
‘client_secret’ => $params[‘client_secret’],
‘refresh_token’ => $token[‘refresh_token’],
‘grant_type’ => ‘refresh_token’
);

$response = _do_post($url, $fields);
return $response;
}

function _do_post($url, $fields)
{
$fields_string = “”;

foreach ($fields as $key => $value)
{
$fields_string .= $key . “=” . $value . “&”;
}
$fields_string = rtrim($fields_string, “&”);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$response = curl_exec($ch);
curl_close($ch);

return $response;
}

function _get_user_info($AuthToken){
$url = “https://www.googleapis.com/oauth2/v1/userinfo”;
$fields = array(‘access_token’ => $AuthToken );
$response = _do_get($url, $fields);

//$response = logoutOauthTwoUser($AuthToken);
return $response;
}

function _do_get($url, $fields)
{
$fields_string = “”;

foreach ($fields as $key => $value)
{
$fields_string .= $key . “=” . $value . “&”;
}
$fields_string = rtrim($fields_string, “&”);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url.”?”.$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPGET, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$response = curl_exec($ch);
curl_close($ch);

return $response;
}

?>

— END —

Author: Khaleel Shaik, JAVA Practice Head & Technical Architect at Bodhtree. He specializes in JAVA/J2EE Technologies; Applications Integration using the SOA web services technologies with more focus on Oracle Fusion Middleware (BPEL/ OSB/ BAM/ B2B/ Oracle Application Adapter/ etc.)

Read More

The Opportunity for Excellence

When working with clients or prospects, I always relished and appreciated an “Opportunity for Excellence“. What does that mean? It means that when a client or prospect calls with a specific problem that is time sensitive and we, as an organization and team, jump on the problem and work to solve it.

We have had several “Opportunities for Excellence” in the past few months’ with our clientele. On two of them we worked through the Christmas holidays. We have had numerous times where we had several of our colleagues pull “all-nighters” just to respond to a client’s needs. We have met deadlines, pushed ourselves, strived to turn out the best work we could do.

This excellence at my organization can only be exhibited by the members i.e. our employees. When will you have an “opportunity for excellence”? When will you be called upon to deliver success in impossible timeframes and conditions?

Let me end by telling you this. When you go the extra mile for your customer and succeed, you go from being a vendor to being a strategic partner.

Phil Hodsdon, SVP, Sales & Solutions at Bodhtree.

Read More

Extending SAP Business Objects to All Organizational Decision-Makers

BI tools play a vital role in decision making and innovation at every level in dynamic organizations. SAP Business Objects includes tools that help expand the reach of BI Information services, enabling the organization to share, integrate and also Embed BI in applications, services, tools and business processes.

Unification of the BI data used across applications

BI can be used across multiple functions and is generally not specific to any particular department or team. It can be leveraged across applications related to finance, operations, sales or human resources. SAP Business Objects Enterprise provides a unified structure with a powerful semantic layer and integration capability that brings a “single version of the truth” to data drawn from multiple sources.

Share BI with any service-Enabled Application

To build applications that extend the advantage of a company’s BI Investment, developers can use SAP Business Objects BI Software Development Kits (SDK’s). These SDK’s can be used in any Java or .Net based application for authentication, authorization, scheduling, content display, ad hoc query, or server administration. SAP Business Objects also offers a comprehensive set of Web Services that expose BI functionality as a platform-agnostic interface. The software also supports your organization by extending the reach of BI beyond traditional corporate business.

SAP Business Objects Web Services enhances support for your tactical and operation decision making, which improves Business process efficiency.

Sridurga Vannemreddi is an SAP Business Objects and Big Data developer with Bodhtree.  For more than a decade, Bodhtree has specialized in business analytics, leveraging close partnerships with leading BI software manufacturers such as SAP Business Objects, Informatica, and IBM Cognos.  Bodhtree offers free assessments to map analytics solutions to the goals and objectives specific to your organization.

Read More

What is Hive? Its Interaction with Hadoop and Big Data

Hive – A Warehousing Solution Over a MapReduce Framework

What is Hive?

Hive is a data warehousing infrastructure built on top of apache Hadoop.

Hadoop provides massive scale-out and fault-tolerance capabilities for data storage and processing (using the MapReduce programming paradigm) on commodity hardware.

Hive enables easy data summarization, ad-hoc querying and analysis of large volumes of data.

It is best used for batch jobs over large sets of immutable data (like web logs).

It provides a simple query language called Hive QL, which is based on SQL and which enables users familiar with SQL to easily perform ad-hoc querying, summarization and data analysis.

At the same time, Hive QL also allows traditional MapReduce programmers to be able to plug in their custom mappers and reducers to do more sophisticated analysis that may not be supported by the built-in capabilities of the languag

Hive Query Language capabilities:

Hive query language provides the basic SQL like operations. These operations work on tables or partitions.

  • Ability to create and manage tables and partitions (create, drop and alter).
  • Ability to support various Relational, Arithmetic and Logical Operators.
  • Ability to do various joins between two tables.
  • Ability to evaluate functions like aggregations on multiple “group by” columns in a table.
  • Ability to store the results of a query into another table.
  • Ability to download the contents of a table to a local directory.
  • Ability to create an external table that points to a specified location within HDFS
  • Ability to store the results of a query in an HDFS directory.
  • Ability to plug in custom scripts using the language of choice for custom map/reduce jobs.

Major Components of Hive and its interaction with Hadoop:

Hive provides external interfaces like command line (CLI) and web UI, and application programming interfaces (API) like JDBC and ODBC

(click to enlarge)

The Hive Thrift Server exposes a very simple client API to execute HiveQL statements. Thrift is a framework for cross-language services, where a server written in one language (like Java) can also support clients in other languages.

The Metastore is the system catalog. All other components of Hive interact with the Metastore.

The Driver manages the life cycle of a HiveQL statement during compilation, optimization and execution.

The Compiler is invoked by the driver upon receiving a HiveQL statement. The compiler translates this statement into a plan which consists of a DAG of map/reduce jobs.

The driver submits the individual map/reduce jobs from the DAG to the Execution Engine in a topological order. Hive currently uses Hadoop as its execution engine.

What Hive is NOT

Hive is not designed for online transaction processing and does not offer real-time queries and row-level updates.

Hive aims to provide acceptable (but not optimal) latency for interactive data browsing, queries over small data sets or test queries.

Hive Applications:

  • Log processing
  • Text mining
  • Document indexing
  • Customer-facing business intelligence (e.g., Google Analytics)
  • Predictive modeling, hypothesis testing

Vijaya R Kolli is a Hadoop-Big Data developer with Bodhtree.  Bodhtree specializes in BI and Big Data solutions, providing analytics consulting, implementation, data cleansing, and maintenance services.

Read More