
net.oauth2.client.http.javase.HttpsURLConnectionClientAdapter Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2017 Georgi Pavlov ([email protected]).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the MIT license which accompanies
* this distribution, and is available at
* https://github.com/tengia/oauth-2/blob/master/LICENSE
*/
package net.oauth2.client.http.javase;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.util.Collection;
import javax.net.ssl.HttpsURLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import commons.io.IOs;
import net.oauth2.AccessToken;
import net.oauth2.AccessTokenGrantRequest;
import net.oauth2.ProtocolError;
import net.oauth2.client.OAuth2ProtocolException;
import net.oauth2.client.http.DataBindingProvider;
import net.oauth2.client.http.FormEncodeDataBinding;
import net.oauth2.client.http.FormEncodeDataBinding.CollectionSerializer;
import net.oauth2.client.http.TokenServiceHttpClient;
import net.oauth2.client.http.javase.conn.AuthenticationAdapter;
import net.oauth2.client.http.javase.conn.BasicAuthenticationAdapter;
import net.oauth2.client.http.javase.conn.HttpLoggingFormatter;
import net.oauth2.client.http.javase.conn.HttpsUrlConnectionFactory;
/**
* A OAuth Token Service HTTP client adapter based on Java SE HttpsUrlConnection with no external dependencies.
*/
public class HttpsURLConnectionClientAdapter implements TokenServiceHttpClient {
protected static final Logger LOGGER = LoggerFactory.getLogger(HttpsURLConnectionClientAdapter.class);
private final URL baseSeviceUrl;
private final HttpLoggingFormatter logFormat;
private final HttpsUrlConnectionFactory connectionFactory;
@SuppressWarnings("rawtypes")
private final Class tokenClass;
private final DataBindingProvider> dataBindingProvider;
private static final FormEncodeDataBinding grantRequestFormEncoder = new FormEncodeDataBinding()
.with("scope", new CollectionSerializer>());//TODO
public HttpsURLConnectionClientAdapter(URL baseSeviceUrl,
HttpsUrlConnectionFactory connectionFactory, HttpLoggingFormatter logFormat,
DataBindingProvider> dataBindingProvider, Class tokenClass) {
this.connectionFactory = connectionFactory;
this.logFormat = logFormat;
this.dataBindingProvider = dataBindingProvider;
this.tokenClass = tokenClass;
this.baseSeviceUrl = baseSeviceUrl;
}
public static final class Builder {
URL baseSeviceUrl;
HttpLoggingFormatter logFormatter;
ConnectionFactory connectionFactory;
Proxy proxy;
DataBindingProvider> dataBindingProvider;
Class> tokenClass;
public Builder() {
}
public Builder baseUrl(String url) throws MalformedURLException {
if(url == null)
throw new IllegalArgumentException("url is null");
this.baseSeviceUrl = new URL(url);
return this;
}
public Builder logFormatter(HttpLoggingFormatter logFormatter) {
this.logFormatter = logFormatter;
return this;
}
public Builder basicAuthentication(String username, String password) {
if (this.connectionFactory != null)
throw new IllegalStateException("connectionFactory has already been set");
AuthenticationAdapter authenticationAdapter = new BasicAuthenticationAdapter(username, password);
this.connectionFactory = new ConnectionFactory(this.proxy, authenticationAdapter);
return this;
}
public Builder withProxy(Proxy proxy) {
this.proxy = proxy;
return this;
}
public Builder connectionFactory(ConnectionFactory connectionFactory) {
if(connectionFactory == null)
throw new IllegalArgumentException("connectionFactory is null");
this.connectionFactory = connectionFactory;
return this;
}
public Builder tokenClass(Class tokenClass) {
if(tokenClass == null)
throw new IllegalArgumentException("tokenClass is null");
this.tokenClass = tokenClass;
return this;
}
public Builder mapper(DataBindingProvider> dataBindingProvider) {
if(dataBindingProvider == null)
throw new IllegalArgumentException("dataBindingProvider is null");
this.dataBindingProvider = dataBindingProvider;
return this;
}
@SuppressWarnings("unchecked")
public HttpsURLConnectionClientAdapter build() throws MalformedURLException {
if (this.baseSeviceUrl == null)
throw new IllegalStateException("baseUrl is required but never invoked");
if (this.connectionFactory == null)
throw new IllegalStateException("connectionFactory is required but never invoked");
if (this.dataBindingProvider == null)
throw new IllegalStateException("databinding provider is not set");
if (this.logFormatter == null)
this.logFormatter = new HttpLoggingFormatter();
if (this.tokenClass == null)
this.tokenClass = (Class) AccessToken.class;
return new HttpsURLConnectionClientAdapter(this.baseSeviceUrl, this.connectionFactory, this.logFormatter,
this.dataBindingProvider, (Class) this.tokenClass);
}
}
@Override
public T post(String urlPath, AccessTokenGrantRequest grantRequest) throws IOException, OAuth2ProtocolException {
// construct request path
URL url = null;
if (urlPath != null)
url = new URL(this.baseSeviceUrl, urlPath);
else
url = this.baseSeviceUrl;
// encode grant for www.form-encode entity payload
String formPayload = grantRequestFormEncoder.encode(grantRequest, null);
// get a new connection
HttpsURLConnection connection = this.connectionFactory.connection(url);
// http communication
String responsePayload = this.httpPostForm(connection, formPayload);
// bind object payload to java object model
@SuppressWarnings("unchecked")
T token = (T) this.dataBindingProvider.parseToken(responsePayload, this.tokenClass);
return token;
}
private String httpPostForm(HttpsURLConnection connection, String formPayload) throws OAuth2ProtocolException, IOException {
OutputStream out = null;
InputStream in = null;
String response = "";
String errorDetails = "";
try {
// Post payload
LOGGER.debug(logFormat.formatRequest(connection, formPayload));
out = connection.getOutputStream();
IOs.produce(out, formPayload);
// Get Response
int httpCode = connection.getResponseCode();
if (httpCode < 400) {
// handle success
in = connection.getInputStream();
response = IOs.consume(in);
} else {
// handle errors
final InputStream errorDetailsStream = connection.getErrorStream();
errorDetails = IOs.consume(errorDetailsStream);
String contentType = connection.getHeaderField("Content-Type");
int idx = contentType.indexOf(";");
if(idx > -1){
contentType = contentType.substring(0, idx);
}
this.handleProtocolError(httpCode, errorDetails, contentType);
}
} finally {
if (out != null)
try {
out.flush();
out.close();
} catch (IOException e) {
/* ignore */}
if (in != null)
try {
in.close();
} catch (IOException e) {
/* ignore */}
if (connection != null)
connection.disconnect();
LOGGER.debug(logFormat.formatResponse(connection, response, errorDetails));
}
return response;
}
protected void handleProtocolError(int code, String responsePayload, String contentType) throws IOException {
String errorMsg = "Token post request failed";
IOException ex = null;
if (responsePayload == null || responsePayload.length() < 1 || contentType == null || !"application/json".equals(contentType)) {
ex = new IOException(errorMsg);
} else {
if(contentType!=null && responsePayload!=null){
String subtype = contentType.substring(contentType.indexOf("/")+1, contentType.length());
if(subtype.startsWith("json")){
ProtocolError error = this.dataBindingProvider.parseError(responsePayload, ProtocolError.class);
ex = new OAuth2ProtocolException(error);
errorMsg = String.format("%s. [%s]: %s", errorMsg, error.getError(), error.getDescription());
} else {
errorMsg = responsePayload; //really?
}
}
}
//catch all
if(ex == null)
ex = new IOException(errorMsg);
LOGGER.error(errorMsg);
throw ex;
}
static class ConnectionFactory implements HttpsUrlConnectionFactory {
private final Proxy proxy;
private final AuthenticationAdapter authenticationAdapter;
ConnectionFactory() {
this.proxy = null;
this.authenticationAdapter = null;
}
ConnectionFactory(final Proxy proxy, AuthenticationAdapter authenticationAdapter) {
this.proxy = proxy;
this.authenticationAdapter = authenticationAdapter;
}
@Override
public HttpsURLConnection connection(URL url) throws IOException {
HttpsURLConnection connection = null;
if (this.proxy != null)
connection = (HttpsURLConnection) url.openConnection(this.proxy);
else
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
if (this.authenticationAdapter != null)
this.authenticationAdapter.adapt(connection);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
return connection;
}
}
/* public static void main(String[] args) throws IOException {
HttpsURLConnectionClientAdapter adapter = new HttpsURLConnectionClientAdapter(
new URL("https://oauthasservices-a25bdd9cf.hana.ondemand.com/oauth2/api/v1/"),
new ConnectionFactory(null, new BasicAuthenticationAdapter("794e1695-35ad-3adb-8f2b-047a269f4f22", "abcd1234")),
new HttpLoggingFormatter(), new JacksonDataBindingProvider(), AccessToken.class);
AccessToken token = adapter.post("token", new ClientCredentialsGrantRequest("794e1695-35ad-3adb-8f2b-047a269f4f22", "abcd1234", null));
System.out.println(token);
}*/
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy