Calling a web service using WS via an HTTP proxy - web-services

I am trying to call a web service from a playframework 2 application running in an environment where I need to go through a proxy server to access external web services. In my application.conf file I have added the following properties:
http.proxyPort=8000
http.proxyHost=myproxyhost.innitech.com
In my play application code I can access the system properties and verify they have been picked up. However, at runtime the proxy configuration is not being used. If I run the application in an environment where I do not need to use the proxy to access the service, the service call works fine.
Is it possible to call web services via a proxy using the play framework, and if so, how?
Here's an example of the call:
def watched(username: String, password: String): Promise[Seq[Repo]] = {
val promiseResponse = WS.url(baseUrl + "/user/watched")
.withAuth(username, password, com.ning.http.client.Realm.AuthScheme.BASIC)
.get
promiseResponse.map(_.json.as[Seq[Repo]])
}
The following stack trace represents what I see at run time:
play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[Connec
tException: https://api.github.com/user]]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:82) [p
lay_2.9.1.jar:2.0]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:63) [p
lay_2.9.1.jar:2.0]
at akka.actor.Actor$class.apply(Actor.scala:290) [akka-actor.jar:2.0]
at play.core.ActionInvoker.apply(Invoker.scala:61) [play_2.9.1.jar:2.0]
at akka.actor.ActorCell.invoke(ActorCell.scala:617) [akka-actor.jar:2.0]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:179) [akka-actor.jar:2.0]
Caused by: java.net.ConnectException: https://api.github.com/user
at com.ning.http.client.providers.netty.NettyConnectListener.operationCo
mplete(NettyConnectListener.java:100) ~[async-http-client.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultCh
annelFuture.java:397) ~[netty.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.addListener(DefaultChann
elFuture.java:143) ~[netty.jar:na]
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.doConnect
(NettyAsyncHttpProvider.java:1004) ~[async-http-client.jar:na]
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.execute(N
ettyAsyncHttpProvider.java:829) ~[async-http-client.jar:na]
at com.ning.http.client.AsyncHttpClient.executeRequest(AsyncHttpClient.j
ava:499) ~[async-http-client.jar:na]
Caused by: java.nio.channels.UnresolvedAddressException: null
at sun.nio.ch.Net.checkAddress(Net.java:30) ~[na:1.6.0_25]
at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:480) ~[na
:1.6.0_25]
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.connec
t(NioClientSocketPipelineSink.java:142) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventS
unk(NioClientSocketPipelineSink.java:105) ~[netty.jar:na]
at org.jboss.netty.handler.ssl.SslHandler.handleDownstream(SslHandler.ja
va:459) ~[netty.jar:na]
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream
(OneToOneEncoder.java:55) ~[netty.jar:na]

The current snapshot in github should fix this problem, as it builds a AsyncHttpClientConfig using the Play context, then initializes the AsynchHttpClient using the config:
lazy val client = {
import play.api.Play.current
val config = new AsyncHttpClientConfig.Builder()
.setConnectionTimeoutInMs(current.configuration.getMilliseconds("ws.timeout").getOrElse(120000L).toInt)
.setFollowRedirects(current.configuration.getBoolean("ws.followRedirects").getOrElse(true))
.setUseProxyProperties(current.configuration.getBoolean("ws.useProxyProperties").getOrElse(true))
current.configuration.getString("ws.useragent").map { useragent =>
config.setUserAgent(useragent)
}
new AsyncHttpClient(config.build())
}

Related

visual studio 2022 aspnetcore 6 web api template https stop working

I am trying to run a web api application created with Visual Studio 2022 on my windows 10 laptop and keep receiving this ERR_SSL_VERSION_OR_CIPHER_MISMATCH, both on Chrome and Edge.
The startup code for the application:
using Microsoft.AspNetCore.Authentication.Negotiate;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
I remember it did worked for sometime ago. Any idea this happens?
From connection log I got this exception.
Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware | Failed to authenticate HTTPS connection. System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> System.ComponentModel.Win32Exception (0x80090331): The client and server cannot communicate, because they do not possess a common algorithm.
at System.Net.SSPIWrapper.AcquireCredentialsHandle(ISSPIInterface secModule, String package, CredentialUse intent, SCH_CREDENTIALS* scc)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCH_CREDENTIALS* secureCredential)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandleSchCredentials(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)

Front end of the notary in cordapp-samples

I want to set up the UI for the notary in cordApp samples. As the notary's Web port is not configured by default,I am trying to change the client's Gradle file to configure the notary.
Is there any other way to configure the notary's UI ?
I checked,It can be seen through the Node Explorer.Is there any other way to check the notary on web front?
You can configure the notary's webport in a similar way as you would configure for any other node.
Your notary must have an RPC address configured.
Once you have an rpc address configured, you can either use the default corda webserver (which is now deprecated) or you must configure your own webserver or use spring-webserver).
Without specifying the web port you can define your spring boot server, and connect to the node via RPC.
Step 1 Define your Spring boot server
#SpringBootApplication
private open class Starter
/**
* Starts our Spring Boot application.
*/
fun main(args: Array<String>) {
val app = SpringApplication(Starter::class.java)
app.setBannerMode(Banner.Mode.OFF)
app.isWebEnvironment = true
app.run(*args)
}
Step 2 Start your server by defining a starter task in your gradle build file
task runPartyAServer(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.server.ServerKt'
}
Step 3 Define the rpc configuration used to connect to the node.
server.port=10055
config.rpc.username=user1
config.rpc.password=test
config.rpc.host=localhost
config.rpc.port=10008
Step 4 Connect to the node using the above config defined.
val rpcAddress = NetworkHostAndPort(host, rpcPort)
val rpcClient = CordaRPCClient(rpcAddress)
val rpcConnection = rpcClient.start(username, password)
proxy = rpcConnection.proxy
Step 5 Use the proxy to connect to the notary node.
You can refer to the complete code here.

S3Client and Quarkus Native App Issueu with Runn

I am trying to create a lambda S3 listener leveraging Lambda as a native image. The point is to get the S3 event and then do some work by pulling the file, etc. To get the file I am using het AWS 2.x S3 client as below
S3Client.builder().httpClient().build();
This code results in
2020-03-12 19:45:06,205 ERROR [io.qua.ama.lam.run.AmazonLambdaRecorder] (Lambda Thread) Failed to run lambda: software.amazon.awssdk.core.exception.SdkClientException: Unable to load an HTTP implementation from any provider in the chain. You must declare a dependency on an appropriate HTTP implementation or pass in an SdkHttpClient explicitly to the client builder.
To resolve this I added the aws apache client and updated the code to do the following:
SdkHttpClient httpClient = ApacheHttpClient.builder().
maxConnections(50).
build()
S3Client.builder().httpClient(httpClient).build();
I also had to add:
[
["org.apache.http.conn.HttpClientConnectionManager",
"org.apache.http.pool.ConnPoolControl","software.amazon.awssdk.http.apache.internal.conn.Wrapped"]
]
After this I am now getting the following stack trace:
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:86)
... 76 more
I am running version 1.2.0 of qurkaus on 19.3.1 of graal. I am building this via Maven and the the provided docker container for Quarkus. I thought the trust store was added by default (in the build command it looks to be accurate) but am I missing something? Is there another way to get this to run without the setting of the HttpService on the S3 client?
There is a PR, under review at the moment, that introduces AWS S3 extension both JVM & Native. AWS clients are fully Quarkified, meaning configured via application.properties and enabled for dependency injection. So stay tuned as it most probably be available in Quarkus 1.5.0

Running Spring Boot App in AWS does not start

I have a Spring Boot application that starts without problem when executed locally.
I want to run the app via AWS Lambda. I used the https://github.com/awslabs/aws-serverless-java-container and added the corresponding code as described in this sample: https://keyholesoftware.com/2018/04/26/aws-lambda-with-spring-boot/ .
The Problem is, that it throws an exception that it cannot find the Context, when run as Lambda in the AWS:
Caused by: java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:84)
at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.initialize(SpringBootLambdaContainerHandler.java:181)
at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.getAwsProxyHandler(SpringBootLambdaContainerHandler.java:77)

DefaultHandshakeHandler's determineUser not called on Production Server

I have a grails project which uses Spring websockets. I have implemented the DefaultHandshakeHandler to create random principal name for each new session and use convertAndSendToUser to send messages.
Everything works fine in local run. I am also able to deploy the WAR file on an AWS EC2 Linux Instance running latest tomcat. The file deploys fine and the Connect and Disconnect events on websockets can be detected correctly.*
The only problem is, My CustomHandshakeHandler's determineUser does not get called on production. Due to this my StompHeaderAccessor's principal is always null and the code starts spitting NPEs.
This is how i have declared the CustomHandshakeHandler :
class CustomHandshakeHandler extends DefaultHandshakeHandler {
#Override
protected Principal determineUser(ServerHttpRequest request,
WebSocketHandler wsHandler,
Map<String, Object> attributes) {
// Generate principal with UUID as name
return new StompPrincipal(UUID.randomUUID().toString())
}
}
This is how i set the handshake handler configuration :
#Override
void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/ws-ep") // Set websocket endpoint to connect to
.setHandshakeHandler(new CustomHandshakeHandler()) // Set custom handshake handler
.withSockJS() // Add Sock JS support for frontend
}
I tried deploying the same WAR file on local Tomcat 8 and it again works fine. It seems problem happens due to AWS. I also searched for some other AWS and websocket related issues. I came across some ELB compatibility related things but i Don't think that's my case since my websockets are working fine (Events are being received)
Can someone please help out or point me in right directions
Problem was with Nginx settings which upgrade the Http Request to WS request. This question helped a lot : Spring WebSocket: Handshake failed due to invalid Upgrade header: null