Java tutorial
/* * Copyright (C) 2014 Tirasa * * 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.tirasa.olingooauth2; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpHeaders; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponse; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.apache.olingo.client.core.http.AbstractOAuth2HttpClientFactory; import org.apache.olingo.client.core.http.OAuth2Exception; public class AzureADOAuth2HttpClientFactory extends AbstractOAuth2HttpClientFactory { private final String clientId; private final String redirectURI; private final String resourceURI; private final UsernamePasswordCredentials creds; private ObjectNode token; public AzureADOAuth2HttpClientFactory(final String authority, final String clientId, final String redirectURI, final String resourceURI, final UsernamePasswordCredentials creds) { super(URI.create(authority + "/oauth2/authorize"), URI.create(authority + "/oauth2/token")); this.clientId = clientId; this.redirectURI = redirectURI; this.resourceURI = resourceURI; this.creds = creds; } @Override protected boolean isInited() throws OAuth2Exception { return token != null; } private void fetchAccessToken(final DefaultHttpClient httpClient, final List<BasicNameValuePair> data) { token = null; InputStream tokenResponse = null; try { final HttpPost post = new HttpPost(oauth2TokenServiceURI); post.setEntity(new UrlEncodedFormEntity(data, "UTF-8")); final HttpResponse response = httpClient.execute(post); tokenResponse = response.getEntity().getContent(); token = (ObjectNode) new ObjectMapper().readTree(tokenResponse); } catch (Exception e) { throw new OAuth2Exception(e); } finally { IOUtils.closeQuietly(tokenResponse); } } @Override protected void init() throws OAuth2Exception { final DefaultHttpClient httpClient = wrapped.create(null, null); // 1. access the OAuth2 grant service (with authentication) String code = null; try { final URIBuilder builder = new URIBuilder(oauth2GrantServiceURI).addParameter("response_type", "code") .addParameter("client_id", clientId).addParameter("redirect_uri", redirectURI); HttpResponse response = httpClient.execute(new HttpGet(builder.build())); final String loginPage = EntityUtils.toString(response.getEntity()); String postURL = StringUtils.substringBefore( StringUtils.substringAfter(loginPage, "<form id=\"credentials\" method=\"post\" action=\""), "\">"); final String ppsx = StringUtils.substringBefore(StringUtils.substringAfter(loginPage, "<input type=\"hidden\" id=\"PPSX\" name=\"PPSX\" value=\""), "\"/>"); final String ppft = StringUtils.substringBefore(StringUtils.substringAfter(loginPage, "<input type=\"hidden\" name=\"PPFT\" id=\"i0327\" value=\""), "\"/>"); List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>(); data.add(new BasicNameValuePair("login", creds.getUserName())); data.add(new BasicNameValuePair("passwd", creds.getPassword())); data.add(new BasicNameValuePair("PPSX", ppsx)); data.add(new BasicNameValuePair("PPFT", ppft)); HttpPost post = new HttpPost(postURL); post.setEntity(new UrlEncodedFormEntity(data, "UTF-8")); response = httpClient.execute(post); final String samlPage = EntityUtils.toString(response.getEntity()); postURL = StringUtils.substringBefore( StringUtils.substringAfter(samlPage, "<form name=\"fmHF\" id=\"fmHF\" action=\""), "\" method=\"post\" target=\"_top\">"); final String wctx = StringUtils.substringBefore(StringUtils.substringAfter(samlPage, "<input type=\"hidden\" name=\"wctx\" id=\"wctx\" value=\""), "\">"); final String wresult = StringUtils.substringBefore(StringUtils.substringAfter(samlPage, "<input type=\"hidden\" name=\"wresult\" id=\"wresult\" value=\""), "\">"); final String wa = StringUtils.substringBefore( StringUtils.substringAfter(samlPage, "<input type=\"hidden\" name=\"wa\" id=\"wa\" value=\""), "\">"); data = new ArrayList<BasicNameValuePair>(); data.add(new BasicNameValuePair("wctx", wctx)); data.add(new BasicNameValuePair("wresult", wresult.replace(""", "\""))); data.add(new BasicNameValuePair("wa", wa)); post = new HttpPost(postURL); post.setEntity(new UrlEncodedFormEntity(data, "UTF-8")); response = httpClient.execute(post); final Header locationHeader = response.getFirstHeader("Location"); if (response.getStatusLine().getStatusCode() != 302 || locationHeader == null) { throw new OAuth2Exception("Unexpected response from server"); } final String[] oauth2Info = StringUtils .split(StringUtils.substringAfter(locationHeader.getValue(), "?"), '&'); code = StringUtils.substringAfter(oauth2Info[0], "="); EntityUtils.consume(response.getEntity()); } catch (Exception e) { throw new OAuth2Exception(e); } if (code == null) { throw new OAuth2Exception("No OAuth2 grant"); } // 2. ask the OAuth2 token service final List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>(); data.add(new BasicNameValuePair("grant_type", "authorization_code")); data.add(new BasicNameValuePair("code", code)); data.add(new BasicNameValuePair("client_id", clientId)); data.add(new BasicNameValuePair("redirect_uri", redirectURI)); data.add(new BasicNameValuePair("resource", resourceURI)); fetchAccessToken(httpClient, data); if (token == null) { throw new OAuth2Exception("No OAuth2 access token"); } } @Override protected void accessToken(final DefaultHttpClient client) throws OAuth2Exception { client.addRequestInterceptor(new HttpRequestInterceptor() { @Override public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { request.removeHeaders(HttpHeaders.AUTHORIZATION); request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token.get("access_token").asText()); } }); } @Override protected void refreshToken(final DefaultHttpClient client) throws OAuth2Exception { final List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>(); data.add(new BasicNameValuePair("grant_type", "refresh_token")); data.add(new BasicNameValuePair("refresh_token", token.get("refresh_token").asText())); fetchAccessToken(wrapped.create(null, null), data); if (token == null) { throw new OAuth2Exception("No OAuth2 refresh token"); } } }