I'm using Google's gRPC library to access data from my GCP domain.
My code performs authentication using a service account JSON key.
It worked fine for about a month, until recently I started receiving the following error on any action I try to perform:
{"error":"invalid_grant","error_description":"Invalid JWT Signature."}
I should note that the authentication process executes without errors, as does creation of the service object (see Java code example below). The error is thrown when I try to perform any data access action, e.g. the listSecrets method in the example below.
Searching for this problem on the web, I have found mainly answers that point to a system time/timezone error; however, the date & time & timezone on my computer are completely accurate.
Any suggestions?
Example of my Java code:
String projectId = "my-project";
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("C:\\Users\\elisha.l\\Downloads\\co-club-project-01-3588a3330456.json"));
SecretManagerServiceClient client = SecretManagerServiceClient.create();
ProjectName parent = ProjectName.of(projectId);
ListSecretsPagedResponse response = client.listSecrets(parent);
Stacktrace of the error:
Exception in thread "main" com.google.api.gax.rpc.UnavailableException: io.grpc.StatusRuntimeException: UNAVAILABLE: Credentials failed to obtain metadata
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:69)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60)
at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:68)
at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1050)
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1176)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:969)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:760)
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:563)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:533)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:434)
at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:763)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:742)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57)
at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.listSecrets(SecretManagerServiceClient.java:245)
at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.listSecrets(SecretManagerServiceClient.java:196)
at google.Secret.main(Secret.java:26)
Caused by: io.grpc.StatusRuntimeException: UNAVAILABLE: Credentials failed to obtain metadata
at io.grpc.Status.asRuntimeException(Status.java:533)
... 14 more
Caused by: java.io.IOException: Error getting access token for service account: 400 Bad Request
POST https://oauth2.googleapis.com/token
{"error":"invalid_grant","error_description":"Invalid JWT Signature."}
at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:444)
at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:157)
at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:145)
at com.google.auth.oauth2.ServiceAccountCredentials.getRequestMetadata(ServiceAccountCredentials.java:603)
at com.google.auth.Credentials.blockingGetToCallback(Credentials.java:112)
at com.google.auth.Credentials$1.run(Credentials.java:98)
... 7 more
Caused by: com.google.api.client.http.HttpResponseException: 400 Bad Request
POST https://oauth2.googleapis.com/token
{"error":"invalid_grant","error_description":"Invalid JWT Signature."}
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1113)
at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:441)
... 12 more
I should note that the authentication process executes without errors, as does creation of the service object (see Java code example below). The error is thrown when I try to perform any data access action, e.g. the listSecrets method in the example below.
I think you are saying that the instantiation of the GoogleCredentials and SecretManagerServiceClient objects do not throw any exceptions. But these don't actually validate your credentials until you invoke a method on the client object, like listServices. (Please let me know if I misunderstood and some methods on the SecretManagerServiceClient actually validate properly and succeed).
It seems like there is some issue with your service account JSON key, so I would start by determining if it works separately from the Java code. You can follow the instructions at https://cloud.google.com/service-usage/docs/getting-started#test to use oauth2l to get a bearer token from your service account, then invoke the secret manager API directly using this bearer token via curl, as shown in https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets. Something like:
curl "https://secretmanager.googleapis.com/v1/projects/project-id/secrets?secretId=secret-id" \
--request "POST" \
--header "authorization: Bearer <bearer token from oauth2l>" \
--header "content-type: application/json" \
--header "x-goog-user-project: project-id" \
--data "{\"replication\": {\"automatic\": {}}}"
If that works whereas the Java code does not, then you will probably want to proceed by filing an issue on the https://github.com/googleapis/java-secretmanager repository.
Alternatively to all of the above: it may be quicker just to create a new service account and see if that works, versus debugging precisely what's going wrong with the current account.
Related
I'm trying to connect to the Kucoin API using Secure WebSockets (WSS). I'm using JDK 17 and Vert.x 4.3.8 (the latest version at this time). I followed the instructions here.
So currently I have a basic app with two verticles: the first one uses a WebClient to connect to the /api/v1/bullet-public URI to get the WSS endpoint and the token. Once I get an answer, I save these to a local map and publish an event to the bus to connect to the WebSocket feed. This part works fine.
The second verticle consumes the event published by the first one and creates a websocket using the settings saved on the local map. This doesn't work. I tried two slightly different approaches and I get different errors on each.
The first approach is to set the host to ws-api-spot.kucoin.com and the relative URI. The code for this is on this Github gist.
In this case I get the following error:
io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: Connection closed while handshake in process
at io.vertx.core.http.impl.WebSocketHandshakeInboundHandler.channelInactive(WebSocketHandshakeInboundHandler.java:81)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:305)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:418)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:411)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:376)
at io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:329)
at io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:221)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274)
at io.netty.handler.logging.LoggingHandler.channelInactive(LoggingHandler.java:206)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:411)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:376)
at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1075)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:305)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
The second approach is to set the absolute URI to something like this:
wss://ws-api-spot.kucoin.com/endpoint/?token=<token_value>&topic=/market/ticker:btc&response=true
To do this, I slightly modified the getOptions method like this:
private static WebSocketConnectOptions getOptions(LocalMap<String, String> serverDetails) {
WebSocketConnectOptions options = new WebSocketConnectOptions();
options.setMethod(HttpMethod.GET);
options.setAllowOriginHeader(false);
options.setPort(443);
options.setSsl(true);
options.setAbsoluteURI(serverDetails.get("endpoint") + "endpoint/?token=" + serverDetails.get("token") + "&topic=/market/ticker:btc&response=true");
return options;
}
In this case, I get this other error:
io.vertx.core.VertxException: Invalid url: wss://ws-api-spot.kucoin.com/endpoint/?token=<token_value>&topic=/market/ticker:btc&response=true
at io.vertx.core.http.RequestOptions.parseUrl(RequestOptions.java:357)
at io.vertx.core.http.RequestOptions.setAbsoluteURI(RequestOptions.java:370)
at org.phase5.goyena.SymbolSnapshotVerticle.getOptions(SymbolSnapshotVerticle.java:52)
at org.phase5.goyena.SymbolSnapshotVerticle.lambda$start$3(SymbolSnapshotVerticle.java:32)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
at io.vertx.core.eventbus.impl.MessageConsumerImpl.dispatch(MessageConsumerImpl.java:177)
at io.vertx.core.eventbus.impl.HandlerRegistration$InboundDeliveryContext.execute(HandlerRegistration.java:137)
at io.vertx.core.eventbus.impl.DeliveryContextBase.next(DeliveryContextBase.java:72)
at io.vertx.core.eventbus.impl.DeliveryContextBase.dispatch(DeliveryContextBase.java:43)
at io.vertx.core.eventbus.impl.HandlerRegistration.dispatch(HandlerRegistration.java:98)
at io.vertx.core.eventbus.impl.MessageConsumerImpl.deliver(MessageConsumerImpl.java:183)
at io.vertx.core.eventbus.impl.MessageConsumerImpl.doReceive(MessageConsumerImpl.java:168)
at io.vertx.core.eventbus.impl.HandlerRegistration.lambda$receive$0(HandlerRegistration.java:49)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.net.MalformedURLException: unknown protocol: wss
at java.base/java.net.URL.<init>(URL.java:681)
at java.base/java.net.URL.<init>(URL.java:569)
at java.base/java.net.URL.<init>(URL.java:516)
at io.vertx.core.http.RequestOptions.parseUrl(RequestOptions.java:355)
... 20 common frames omitted
When I manually run a request from Postman following the same instructions, I successfully get a connection. Any ideas of what's wrong? Do I need to change the options for either the HTTP client or the Websocket?
Thanks in advance.
I have an application running as a weblogic startup class. When it gets to the point where it has to request a service from my application that is setup with Kerberos Service Principal I get a 401 Unauthorized exception (As seen below).
When I run the application through a normal private static void main method using precisely the same JVM arguments and config files(listed below) it works.
I used Wireshark to see what is going on and I can see that it only tries to use the service once and not twice meaning that Weblogic does not know how to Negotiate authentication. It seems that Weblogic ignores my JVM arguments completely as there is no signs of Kerberos being used at all in Weblogic even with debug=true added to the jvm arguments and the config files. I did also set the logging level to debug and enabled atn and atz in monitoring there is no traces of any Kerberos being used
Here is my arguments (I tested singular and double slashes in my path as well as adding qoutes and not)
set JAVA_OPTIONS_KRB5_CREDS="-Djavax.security.auth.useSubjectCredsOnly=false"
set JAVA_OPTIONS_KRB5_CONF="-Djava.security.auth.login.config=C:\Mywork\wl12213\user_projects\domains\KSS\config\login.conf"
set JAVA_OPTIONS_KRB5_INI="-Djava.security.krb5.conf=C:\Mywork\wl12213\user_projects\domains\KSS\config\krb5.conf"
set JAVA_OPTIONS_KRB5_DEBUG="-Dsun.security.krb5.debug=true"
set JAVA_OPTIONS=%JAVA_OPTIONS% %JAVA_OPTIONS_KRB5_CREDS% %JAVA_OPTIONS_KRB5_CONF% %JAVA_OPTIONS_KRB5_INI% %JAVA_OPTIONS_KRB5_DEBUG%
Here is my main class
URL url = new URL("url to service (Using the url the SPN is registered to)");
QName qname = new QName("schema");
Service service = Service.create(url, qname);
keystoreService = service.getPort(new QName("schema", "KeystoreServiceSoap11"), KeystoreService.class);
GetKeystoreRequest request = new GetKeystoreRequest();
request.setKeystoreType(StoreType.IDENTITY_STORE);
request.setMachineName(machineName);
GetKeystoreResponse response = keystoreService.getKeystore(request);
The login.conf file
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required principal="KHULE" useKeyTab="true" keyTab="C:\\Mywork\\wl12213\\user_projects\\domains\\KSS\\config\\weblogic.keytab" storeKey="true" debug=true;
};
The Exception
Caused by: com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.checkStatusCode(HttpTransportPipe.java:332)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.createResponsePacket(HttpTransportPipe.java:274)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:232)
at weblogic.wsee.jaxws.transport.http.client.WLSHttpTransportPipe.process(WLSHttpTransportPipe.java:30)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:145)
at com.sun.xml.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:110)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1136)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1050)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:1019)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:877)
at com.sun.xml.ws.client.Stub.process(Stub.java:463)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:191)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:108)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy147.getKeystore(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:147)
at com.sun.proxy.$Proxy148.getKeystore(Unknown Source)
at za.co.discovery.security.camanager.clients.weblogic.KeyStoreFactory.getIdentityStore(KeyStoreFactory.java:66)
Can you please help me ?
I am trying to integrate bing translator in my java application. I have registered to Microsoft azure cognitive service and Microsoft market place.
while executing below code
import com.memetix.mst.language.Language;
import com.memetix.mst.translate.Translate;
public class Main {
public static void main(String[] args) {
try{
Translate.setClientId(/* my Client Id */);
Translate.setClientSecret(/* my Client Secret */);
String translatedText = Translate.execute("Bonjour le monde", Language.FRENCH, Language.ENGLISH);
System.out.println(translatedText);
}
catch(Exception e) {
System.err.println("Exception: " + e.getMessage());
}
}
}
I am getting below exception:
Page NoException in thread "main" java.lang.Exception: [microsoft-translator-api] Error retrieving translation : Server returned HTTP response code: 400 for URL: https://datamarket.accesscontrol.windows.net/v2/OAuth2-13
at com.memetix.mst.MicrosoftTranslatorAPI.retrieveString(MicrosoftTranslatorAPI.java:202)
at com.memetix.mst.translate.Translate.execute(Translate.java:61)
at test.SimpleExcelTranalator.main(SimpleExcelTranalator.java:44)
Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: https://datamarket.accesscontrol.windows.net/v2/OAuth2-13
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$10.run(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$10.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at com.memetix.mst.MicrosoftTranslatorAPI.getToken(MicrosoftTranslatorAPI.java:139)
at com.memetix.mst.MicrosoftTranslatorAPI.retrieveResponse(MicrosoftTranslatorAPI.java:160)
at com.memetix.mst.MicrosoftTranslatorAPI.retrieveString(MicrosoftTranslatorAPI.java:199)
... 2 more
Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: https://datamarket.accesscontrol.windows.net/v2/OAuth2-13
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at com.memetix.mst.MicrosoftTranslatorAPI.getToken(MicrosoftTranslatorAPI.java:138)
... 4 more
The datamarket url is where you get your client id and secret from. Is that where you're sending your translation request to? Should be something like
http://api.microsofttranslator.com/v2/Http.svc/Translate?
Also datamarket is being deprecated. You have to switch to Azure Cognitive Services
http://docs.microsofttranslator.com/text-translate.html
According to your referenced package com.memetix.mst.language.* in your code, I searched and found its source code on GitHub, repository on Maven, and an old repository on GoogleCode. I reviewed its source code, and discovered it wrappered the MS Translator Text API from Azure old datamarket web site. The library is out of date with the old REST API, the old website shows "THE MICROSOFT TRANSLATOR API IS NOW AVAILABLE ON THE AZURE PORTAL" and "IMPORTANT: An Azure account is required. Read the steps to get started on the portal here." So first you need to have an Azure subscription to create a Translator Text API service on Azure portal, then write code to call the new REST API. You can refer to my answer for the two other SO threads as below to know how to use the new REST API and call it via my sample code.
My answer for MS Translator returns empty response when used with Azure token shows the new REST API usage.
My answer for Microsoft Translator API Java, How to get client new ID with Azure which includes my sample code, it shows how to call the new REST API in Java.
Hope it helps.
I've deployed a Neo4j unmanaged extension. The unmanaged extension can be called using REST Client and successfully returned the result. The problem is when I try to call / invoke the unmanaged extension from another java class, it keep on throwing the 401 Unauthorized.
I used Spring RestTemplate to invoke the unmanaged extension.
My codes :
RestTemplate restTemplate = new RestTemplate();
PostPhotoRest postPhotoRest = restTemplate.getForObject("http://myneo4jusername:myneo4jpassword#localhost:7474/extension/servicetwo/postphoto/55b12d35-94fd-4297-bb18-e6040d7b7109", PostPhotoRest.class);
Full Error :
Caused by: org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) ~[spring-web-4.3.0.RC2.jar:4.3.0.RC2]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:668) ~[spring-web-4.3.0.RC2.jar:4.3.0.RC2]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:621) ~[spring-web-4.3.0.RC2.jar:4.3.0.RC2]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:581) ~[spring-web-4.3.0.RC2.jar:4.3.0.RC2]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:288) ~[spring-web-4.3.0.RC2.jar:4.3.0.RC2]
at my.winapp.hashtagmanipulation.worker.RabbitMQWorker.processMessage(RabbitMQWorker.java:76) ~[classes/:na]
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-messaging-4.3.0.RC2.jar:4.3.0.RC2]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:115) ~[spring-messaging-4.3.0.RC2.jar:4.3.0.RC2]
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:48) ~[spring-rabbit-1.5.5.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:112) ~[spring-rabbit-1.5.5.RELEASE.jar:na]
... 12 common frames omitted
The driver configuration can supply the URI and credentials configured in ogm.properties.
Components.driver().getConfiguration().getURI();
Components.driver().getConfiguration().getCredentials();
I am writing a posting engine to run on Glassfish which posts to Twitter from a database queue.
I am using the Scribe Java API for doing this. I am having an issue with performing a signRequest from the OAuthService. I have a valid access token and have the tweet to send out - Below is my code for where the error is occuring.
String urlTweet = "https://api.twitter.com/1.1/statuses/update.json?status=Tweet To Post";
OAuthRequest tmpRequest = new OAuthRequest(Verb.POST, urlTweet);
oAuthService.signRequest(accessToken, tmpRequest); // THIS LINE THERE IS AN ERROR
response = tmpRequest.send();
However I am getting an error on the line shown above. Here is the stack trace for what I am getting - parts have been redacted for anonymity purposes.
org.scribe.exceptions.OAuthSignatureException: Error while signing string: POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&[redacted]
at org.scribe.services.HMACSha1SignatureService.getSignature(HMACSha1SignatureService.java:36)
at org.scribe.oauth.OAuth10aServiceImpl.getSignature(OAuth10aServiceImpl.java:151)
at org.scribe.oauth.OAuth10aServiceImpl.addOAuthParams(OAuth10aServiceImpl.java:75)
at org.scribe.oauth.OAuth10aServiceImpl.signRequest(OAuth10aServiceImpl.java:126)
at [redacted].TWScribePost.postTwitter(TWScribePost.java:141)
at [redacted].Post.TWScribePost.post(TWScribePost.java:42)
at [redacted].Post.PostingEng$TWReadQueue.run(PostingEng.java:137)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Caused by: java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available
at javax.crypto.Mac.getInstance(DashoA13*..)
at org.scribe.services.HMACSha1SignatureService.doSign(HMACSha1SignatureService.java:43)
at org.scribe.services.HMACSha1SignatureService.getSignature(HMACSha1SignatureService.java:32)
... 8 more
Try to use response = oAuthService.execute(tmpRequest); instead of response = tmpRequest.send();