Set up Firebase admin sdk with proxy (Java) - java

I'm trying to use firebase to authenticate my users via Google. On my Java server I'm verifying the validity of the idToken and every time I get this error:
com.google.firebase.auth.FirebaseAuthException: Error while verifying token signature.
I identified the problem as being the proxy of my server that avoid the http requests made by the sdk. I tested my code on my computer and it works so I'm pretty sure the problem is the proxy.
Here is my code:
InputStream serviceAccount = getClass().getClassLoader().getResourceAsStream(<fileName>);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(<address>, <port>));
HttpTransport httpTransport = new NetHttpTransport.Builder().setProxy(proxy).build();
HttpTransportFactory httpTransportFactory = () -> httpTransport;
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount, httpTransportFactory))
.setDatabaseUrl(<adress>)
.setHttpTransport(httpTransport)
.build();
FirebaseApp.initializeApp(options);
FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdTokenAsync(<token>).get();
What am I doing wrong ?

I believe this is a bug. As you can see here, the token verifier does not use the HTTP transport injected through options. I'd appreciate if you can create an issue for this on GitHub.
In the meantime, you might be able to get around this limitation by configuring the HTTP/S proxy for the JVM. Try setting the https.proxyHost and https.proxyPort system properties when starting the JVM (more details here).

I've faced the same problem, and still waiting for a greater solution.
In the meantime, I've decompiled the WebSocket class (com.google.firebase.database.tubesock.WebSocket), and created an underlying socket by myself, then droped this decompiled class in a new package in my project: com.google.firebase.database.tubesock.
The creation of the SSLSocket is around the line 295 of this class.
I've created the socket this way:
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
InetSocketAddress proxyAddr = new InetSocketAddress("200.5.92.169", 8080);
Socket underlying = new Socket(new Proxy(Proxy.Type.HTTP, proxyAddr));
underlying.connect(new InetSocketAddress(host, port));
SSLSocket sslSocket = (SSLSocket) factory.createSocket(underlying, host, port, true);

Related

Trying to connect to an SSH server with on-premise proxy type?

I have a new project where I should connect to an SSH server, with a proxy (which is on-premise).
The problem is, that if I don't use proxy, I get an error saying "UnknownHost".
But when I use proxy, it says "JSchException ProxySOCKS5: com.jcraft.jsch.JSchException: fail in SOCKS5 proxy".
I'm pretty new to sockets, proxies and all these kinds of things, so every advice is appreciated.
JSch jsch = new JSch();
jsch.setKnownHosts("known_hosts");
com.jcraft.jsch.Session session = null;
com.jcraft.jsch.ProxySOCKS5 proxy = new ProxySOCKS5("localhost", 20004);
proxy.setUserPasswd(userName, password);
URL url = new URL("http", "<remoteUrl>", 22, filePath, null);
session = jsch.getSession(userName, hostName, 22);
session.setPassword(password);
session.setProxy(proxy );
session.connect(10000);
I did try a different direction, where I don't use jsch, only java.net. That code:
SocketAddress addr = new InetSocketAddress("localhost", 20004);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr);
final String encodedSubaccount = new String(Base64.encodeBase64(subaccount.getBytes()));
final String encodedLocationId = new String(Base64.encodeBase64(locationId.getBytes()));
char[] pwdHelp = [];
Authenticator.setDefault(new Authenticator() {
#Override
protected java.net.PasswordAuthentication getPasswordAuthentication() {
return new java.net.PasswordAuthentication("1." + encodedSubaccount + "." + encodedLocationId , pwdHelp);
}
});
URL url = new URL("http", "<remoteUrl>", 22, filePath, null);
HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
With this approach, there is no error, but when I try to getResponseMessage() or code, then it returns only -1 or null.
Can somebody help me out?
Thanks in advance
I'm not a java developer so I can help you only the infrastructure part of the problem.
UnknownHost: you cannot connect directly that's why you have to use proxy. UnknownHost means java/your machine cannot resolve DNS name to IP address, maybe that DNS name is an inside/private one.
As I see In your java code You try to connect HTTP protocol instead of SSH protocol.
What is the exact task?
Somebody was provided You an on-premise SocksProxy IP and port, and you have to connect via to an inside SSH server?
OR
You have to connect with SSH protocol to the on-premise server to create a local SocksProxy, and you have to connect to an inside server via local SocksProxy?
In the 2. case you can test the connection with ssh command and a web browser:
SSH to on-premise: ssh -D 1080 on-premise_remote_hosntame_or_IP
Setup socksproxy in a webbrowser: Socks proxy ip: 127.0.0.1, port: 1080
In the web browser try to connect to an inside webserver

No effect in setting proxy to AuthenticationContext in KeyVaultClient java

I want to run my Java code to read Azure KeyVault with proxy in Windows server.
I've gone through many posts but could find any working solution. Mostly given for c# but I want for Java. My code is working fine in my local machine but when I'm trying to run same code in Pre-Prod Windows server where I need to set Proxy is not working.
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(authorization, false, service);
//added below 2 lines but don't see any effect
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.server.com", 80));
context.setProxy(proxy);
ClientCredential credentials = new ClientCredential(clientId, clientKey);
Future<AuthenticationResult> future = context.acquireToken(
resource, credentials, null);
result = future.get();
When I'm running the code in my local machine it is running fine with and without proxy setting but in that Windows server it say "Unknown host" exception.
I am not sure if the following would help, but you can have a try.
You can try to find the direct IP of the proxy, and use it in your code:
InetAddress[] allByName = InetAddress.getAllByName("proxy.server.com");
for (InetAddress address : allByName) {
System.out.println(address.getHostAddress());
}
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(allByName[0].getHostAddress(),80););
Or
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(InetAddress.getByName("proxy.server.com"),80));
Maybe the direct IP may work.

Example of using ssl with org.apache.http.impl.bootstrap.HttpServer from Apache HttpCore 4.4.3

I have successfully created an embedded HttpServer using the example at https://hc.apache.org.httpcomponents-core-ga/httpcore/examples/org/apache/http/examples/HttpFileServer.java, which handles http: traffic just fine. Now I would like to extend this to support TLS.
I copied some likely looking code from here: https://hc.apache.org/httpcomponents-core-ga/tutorial/html/blocking-io.html#d5e455
But some parts of it are showing up as deprecated, which makes me wonder whether this example is out of date and whether the tree I'm at is the one where I should be barking. Even if that weren't the case, I am having trouble finding the relationship between HttpServer and DefaultBHttpClientConnection (mentioned in the example). I suspect that I should be using DefaultBHttpServerConnection but I am so far unable to find that either.
Is there a newer example of this anywhere?
Michael D. Spence
Mockingbird Data Systems, Inc.
I am not sure understand the problem you are having. All you need is to provide a correctly initialized SSLContext instance to ServerBoostrap . HttpCore ships with SSLContextBuilder specifically designed to simplify the process of SSLContext initialization.
The example included in HttpCore distribution pretty much shows every step required to set up SSL/TLS transport layer.
SSLContext sslcontext = null;
if (port == 8443) {
// Initialize SSL context
URL url = HttpFileServer.class.getResource("/my.keystore");
if (url == null) {
System.out.println("Keystore not found");
System.exit(1);
}
sslcontext = SSLContexts.custom()
.loadKeyMaterial(url, "secret".toCharArray(), "secret".toCharArray())
.build();
}
SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout(15000)
.setTcpNoDelay(true)
.build();
final HttpServer server = ServerBootstrap.bootstrap()
.setListenerPort(port)
.setServerInfo("Test/1.1")
.setSocketConfig(socketConfig)
.setSslContext(sslcontext)
.setExceptionLogger(new StdErrorExceptionLogger())
.registerHandler("*", new HttpFileHandler(docRoot))
.create();
server.start();

Dynamically set setEnabledProtocols other than SSLSocket.setEnabledProtocols

Hi do any one having idea about setting setEnabledProtocols other than java code
SSLSocket.setEnabledProtocols(newProtocol);
Because in our web service code we couldn't find any socket connection.
Thanks in advance. Appreciate your help if you guide me in setting dynamic UNIX java command.
Like that:
SSLContext context = SSLUtils.createSSLContext();
// Connect to the tracer
SSLSocketFactory factory = context.getSocketFactory();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(endpointId.getHostName(),
endpointId.getPort());
// Enable TLS protocols
SSLParameters params = new SSLParameters();
params.setProtocols(new String[] {"TLSv1", "TLSv1.1","TLSv1.2"});
sslSocket.setSSLParameters(params);
// Initialize the SSL handshake
sslSocket.startHandshake();
I have used System.setproperty("https.protocol","SSLv3"); and now its working fine.

Jetty SslConnector's deprecated methods

SslConnector.java interface has been changed in the newest Jetty 7.3.1.v20110307.
Almost all off the methods have been marked as deprecated without mentioning the replacement interface or methods to use.
I've checked the jetty-users and jetty-dev mailing lists for the information with no luck.
Is there anybody out there who knows how should be the code changed for the future?
Thanks in advance!
Okay, digging out from the subversion changelog for the corresponding commits (crazy) it came out that SslContextFactory should be used.
Example:
final SslContextFactory sslContextFactory = new SslContextFactory(sKeyStore);
sslContextFactory.setKeyStorePassword(sPassword);
final SslSocketConnector conn = new SslSocketConnector(sslContextFactory);
conn.setReuseAddress(true);
// ...
Building on your own answer:
Server server = new Server();
// Encrypt the connection using a valid certificate/keystore
SslContextFactory sslContextFactory = new SslContextFactory("path/keystore.jks");
sslContextFactory.setKeyStorePassword("password");
// Create a new SocketConnector at port 443, which is the default port for
// HTTPS web pages (no port number needs to be specified in the browser).
SslSocketConnector sslConnector = new SslSocketConnector(sslContextFactory);
sslConnector.setPort(443);
// Add the SocketConnector to the server
server.setConnectors(new Connector[] {sslConnector});

Categories

Resources