Java tutorial
/******************************************************************************* * Copyright (c) 2015 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package net.wasdev.gameon.auth.github; import java.io.IOException; import java.nio.charset.Charset; import java.security.GeneralSecurityException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.javanet.NetHttpTransport; import net.wasdev.gameon.auth.JwtAuth; /** * Servlet implementation class googleCallback */ @WebServlet("/GitHubCallback") public class GitHubCallback extends JwtAuth { private static final long serialVersionUID = 1L; @Resource(lookup = "gitHubOAuthKey") String key; @Resource(lookup = "gitHubOAuthSecret") String secret; @Resource(lookup = "authCallbcakURLSuccess") String callbackSuccess; public GitHubCallback() { super(); } @PostConstruct private void verifyInit() { if (callbackSuccess == null) { System.err.println("Error finding webapp base URL; please set this in your environment variables!"); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //ok, we have our code.. so the user has agreed to our app being authed. String code = request.getParameter("code"); String state = (String) request.getSession().getAttribute("github"); //now we need to invoke the access_token endpoint to swap the code for a token. StringBuffer callbackURL = request.getRequestURL(); int index = callbackURL.lastIndexOf("/"); callbackURL.replace(index, callbackURL.length(), "").append("/GitHubCallback"); HttpRequestFactory requestFactory; try { //we'll ignore the ssl cert of the github server for now.. //eventually we may add this to the player truststore.. requestFactory = new NetHttpTransport.Builder().doNotValidateCertificate().build() .createRequestFactory(); //prepare the request.. GenericUrl url = new GenericUrl("https://github.com/login/oauth/access_token"); //set the client id & secret from the injected environment. url.put("client_id", key); url.put("client_secret", secret); //add the code we just got given.. url.put("code", code); url.put("redirect_uri", callbackURL); url.put("state", state); //now place the request to github.. HttpRequest infoRequest = requestFactory.buildGetRequest(url); HttpResponse r = infoRequest.execute(); String resp = "failed."; if (r.isSuccessStatusCode()) { //response comes back as query param encoded data.. we'll grab the token from that... resp = r.parseAsString(); //http client way to parse query params.. List<NameValuePair> params = URLEncodedUtils.parse(resp, Charset.forName("UTF-8")); String token = null; for (NameValuePair param : params) { if ("access_token".equals(param.getName())) { token = param.getValue(); } } if (token != null) { //great, we have a token, now we can use that to request the user profile.. GenericUrl query = new GenericUrl("https://api.github.com/user"); query.put("access_token", token); HttpRequest userRequest = requestFactory.buildGetRequest(query); HttpResponse u = userRequest.execute(); if (u.isSuccessStatusCode()) { //user profile comes back as json.. resp = u.parseAsString(); System.out.println(resp); //use om to parse the json, so we can grab the id & name from it. ObjectMapper om = new ObjectMapper(); JsonNode jn = om.readValue(resp, JsonNode.class); Map<String, String> claims = new HashMap<String, String>(); claims.put("valid", "true"); //github id is a number, but we'll read it as text incase it changes in future.. claims.put("id", "github:" + jn.get("id").asText()); claims.put("name", jn.get("login").textValue()); String jwt = createJwt(claims); //log for now, we'll clean this up once it's all working =) System.out.println("New User Authed: " + claims.get("id") + " jwt " + jwt); response.sendRedirect(callbackSuccess + "/" + jwt); } else { System.out.println(u.getStatusCode()); response.sendRedirect("http://game-on.org/#/game"); } } else { System.out.println("did not find token in github response " + resp); response.sendRedirect("http://game-on.org/#/game"); } } else { response.sendRedirect("http://game-on.org/#/game"); } } catch (GeneralSecurityException e) { throw new ServletException(e); } } }