All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.refinitiv.proxy.authentication.example.ProxyAuthViaSocketChannelExample Maven / Gradle / Ivy
/*|-----------------------------------------------------------------------------
*| This source code is provided under the Apache 2.0 license --
*| and is provided AS IS with no warranty or guarantee of fit for purpose. --
*| See the project's LICENSE.md for details. --
*| Copyright (C) 2019-2022 Refinitiv. All rights reserved. --
*|-----------------------------------------------------------------------------
*/
package com.refinitiv.proxy.authentication.example;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import com.refinitiv.proxy.authentication.CredentialName;
import com.refinitiv.proxy.authentication.IProxyAuthenticatorResponse;
import com.refinitiv.proxy.authentication.ProxyAuthenticationException;
import com.refinitiv.proxy.authentication.ProxyAuthenticatorFactory;
import com.refinitiv.proxy.authentication.CredentialsFactory;
import com.refinitiv.proxy.authentication.IProxyAuthenticator;
import com.refinitiv.proxy.authentication.ICredentials;
import com.refinitiv.proxy.authentication.ResponseCodeException;
public class ProxyAuthViaSocketChannelExample
{
private enum HttpRequestType
{
GET, CONNECT
}
private final int BUFFER_SIZE = 1024 * 1000;
private final ByteBuffer _buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
private final CharBuffer _charBuffer = CharBuffer.allocate(BUFFER_SIZE);
private final CharsetEncoder _encoder;
private final CharsetDecoder _decoder;
private final IProxyAuthenticator _authenticator;
private final String _proxyHost;
private final int _proxyPort;
private final String _actualDestHost;
private final int _actualDestPort;
private SocketChannel _channel; // non-final because we may need to re-open the connection
private static final String EOL = "\r\n";
private static final String USER_AGENT = "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2)\r\n";
private static final String ACCEPT = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";
private static final String PROXY_CONNECTION_KEEP_ALIVE = "Proxy-Connection: Keep-Alive\r\n";
private static final String PRAGMA_NO_CACHE = "Pragma: no-cache\r\n";
private static final String CONNECTION_KEEP_ALIVE = "Connection: Keep-Alive\r\n";
private static final String END_OF_MESSAGE = "\r\n\r\n";
public ProxyAuthViaSocketChannelExample(String proxyHost, int proxyPort, String actualDestHost, int actualDestPort, ICredentials credentials)
throws IOException, ResponseCodeException, ProxyAuthenticationException, InterruptedException
{
_proxyHost = proxyHost;
_authenticator = ProxyAuthenticatorFactory.create(credentials, _proxyHost);
_proxyPort = proxyPort;
_actualDestHost = actualDestHost;
_actualDestPort = actualDestPort;
// init encoder / decoder
Charset charset = Charset.forName("ISO-8859-1");
_encoder = charset.newEncoder();
_decoder = charset.newDecoder();
connect();
}
private void connect() throws IOException
{
System.out.println(String.format("Attempting to connect to proxy %s:%d...", _proxyHost, _proxyPort));
InetSocketAddress socketAddress = new InetSocketAddress(_proxyHost, _proxyPort);
_channel = SocketChannel.open();
_channel.connect(socketAddress);
System.out.println("...successfully connected to the proxy.");
}
public boolean authenticateNio(HttpRequestType establishConnectionVia)
throws CharacterCodingException, IOException, ResponseCodeException, ProxyAuthenticationException
{
boolean authenticated = false;
int ignoredResponses = 0;
final int MAX_IGNORED_RESPONSES = 10;
final StringBuilder response = new StringBuilder();
// Send initial request
String request = buildRequest(establishConnectionVia, false, null);
writeToChannel(request);
// Read response
while ((_channel.read(_buffer)) != -1)
{
_buffer.flip();
_decoder.decode(_buffer, _charBuffer, false);
_charBuffer.flip();
response.append(_charBuffer.toString());
System.out.println(_charBuffer.toString()); // for debugging
if (!_authenticator.isAuthenticated() && !response.toString().contains(END_OF_MESSAGE))
{
_buffer.clear();
_charBuffer.clear();
continue;
}
IProxyAuthenticatorResponse authenticatorResponse = null;
try
{
authenticatorResponse = _authenticator.processResponse(response.toString());
}
catch (ResponseCodeException e)
{
// the response from the proxy may contain an HTML error message intended for uses that we should ignore
++ignoredResponses;
if (ignoredResponses < MAX_IGNORED_RESPONSES)
{
String ignoring = String.format("Ignoring a response from the proxy that did not contain a response code (%d/%d)",
ignoredResponses, MAX_IGNORED_RESPONSES);
System.out.println(ignoring);
_buffer.clear();
_charBuffer.clear();
continue;
}
else
{
throw e;
}
}
_buffer.clear();
_charBuffer.clear();
response.setLength(0);
if (!_authenticator.isAuthenticated())
{
if (authenticatorResponse.isProxyConnectionClose())
{
System.out.println("*** The proxy requested a close. Reconnecting. ***\n\n");
connect();
}
request = buildRequest(establishConnectionVia, false, authenticatorResponse.getProxyAuthorization());
writeToChannel(request);
}
else
{
if (authenticated)
{
break; // we don't want to read any more responses
}
authenticated = true;
if (establishConnectionVia.equals(HttpRequestType.CONNECT))
{
// issue an *https* GET request for content:
request = buildRequest(HttpRequestType.GET, true, null);
writeToChannel(request);
}
else
{
break;
}
}
}
return authenticated;
}
private void writeToChannel(String request) throws CharacterCodingException, IOException
{
System.out.println(); // for debugging
System.out.println(request); // for debugging
ByteBuffer toWrite = _encoder.encode(CharBuffer.wrap(request));
while (toWrite.hasRemaining())
{
_channel.write(toWrite);
}
}
/* Returns a string containing the "common" HTTP Get request.
* A suffix (a trailing \r\n) must be appended to the returned value (to make it a valid HTTP request.)
*/
private final String buildHttpGetRequestPrefix(boolean useHttps)
{
StringBuilder sb = new StringBuilder();
if (useHttps)
{
sb.append("GET https://");
sb.append(_actualDestHost);
sb.append("/");
}
else
{
sb.append("GET http://");
sb.append(_actualDestHost);
sb.append(":");
sb.append(_actualDestPort);
}
sb.append(" HTTP/1.1\r\n");
sb.append(ACCEPT);
sb.append(USER_AGENT);
sb.append("Host: ");
sb.append(_actualDestHost);
// sb.append(":");
// sb.append(_actualDestPort);
sb.append("\r\n");
sb.append(CONNECTION_KEEP_ALIVE);
if (!useHttps)
{
sb.append(PROXY_CONNECTION_KEEP_ALIVE);
}
return sb.toString();
}
/* Returns a string containing the "common" HTTP Connect request.
* A suffix (a trailing \r\n) must be appended to the returned value (to make it a valid HTTP request.)
*/
private final String buildHttpConnectRequestPrefix()
{
StringBuilder sb = new StringBuilder();
sb.append("CONNECT ");
sb.append(_actualDestHost);
sb.append(":");
sb.append(_actualDestPort);
sb.append(" HTTP/1.1\r\n");
sb.append(USER_AGENT);
sb.append(PROXY_CONNECTION_KEEP_ALIVE);
sb.append("Content-Length: 0\r\n");
sb.append("Host: ");
sb.append(_actualDestHost);
sb.append("\r\n");
sb.append(PRAGMA_NO_CACHE);
return sb.toString();
}
private final String buildRequest(HttpRequestType requestMode, boolean useHttps, String authorization)
{
StringBuilder sb = new StringBuilder();
if (requestMode.equals(HttpRequestType.GET))
{
sb.append(buildHttpGetRequestPrefix(false));
}
else
{
sb.append(buildHttpConnectRequestPrefix());
}
if (authorization != null)
{
sb.append(authorization);
}
sb.append(EOL);
return sb.toString();
}
public void close() throws Exception
{
if (_channel != null)
{
try
{
_channel.close();
}
catch (IOException ignored)
{
}
}
}
private static String getLocalHostname()
{
try
{
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ignored)
{
return "localhost"; // for the unlikely event we can't get the actual hostname
}
}
private static ICredentials getCredentials()
{
ICredentials credentials = CredentialsFactory.create();
// NTLM example:
credentials.set(CredentialName.DOMAIN, "EXAMPLE.COM");
credentials.set(CredentialName.USERNAME, "firstname.lastname");
credentials.set(CredentialName.PASSWORD, "abc123");
credentials.set(CredentialName.LOCAL_HOSTNAME, getLocalHostname());
// Negotiate/Kerberos or Kerberos example:
// credentials.set(CredentialName.DOMAIN, "EXAMPLE.COM");
// credentials.set(CredentialName.USERNAME, "firstname.lastname");
// credentials.set(CredentialName.PASSWORD, "abc123");
// credentials.set(CredentialName.KRB5_CONFIG_FILE, "C:\\WINDOWS\\krb5.ini");
return credentials;
}
public static void main(String[] args)
{
final ICredentials credentials = getCredentials();
final String proxyHost = "myProxyHost";
final String actualDestHost = "myProxyHost";
HttpRequestType establishConnectionVia = HttpRequestType.GET; // http or https
final int proxyPort;
final int actualDestPort;
try
{
if (establishConnectionVia.equals(HttpRequestType.GET))
{
proxyPort = 8080;
actualDestPort = 80;
}
else
{
proxyPort = 8443;
actualDestPort = 443;
}
ProxyAuthViaSocketChannelExample test = new ProxyAuthViaSocketChannelExample(proxyHost, proxyPort,
actualDestHost, actualDestPort,
credentials);
if (!test.authenticateNio(establishConnectionVia))
{
System.err.println("Error: Failed to authenticate.");
}
System.out.println("Exiting.");
}
catch (ResponseCodeException e)
{
e.printStackTrace();
}
catch (ProxyAuthenticationException e)
{
e.printStackTrace();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}