Scribe Java Twitter Posting Error - java

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();

Related

GCP: "Invalid JWT Signature" when using Service Account JSON

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.

How can I set a container as public from the v12 Azure Storage Java SDK

I'm trying to programatically create an Azure Storage container with the public read flag on blobs using Java:
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().
endpoint(BLOB_ENDPOINT).
sasToken(BLOB_SAS_TOKEN).
buildClient();
String cName = "my_container_name";
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(cName);
if(!containerClient.exists()) {
// The next line works OK
containerClient.create();
BlobSignedIdentifier identifier = new BlobSignedIdentifier()
.setId("publicreadaccess")
.setAccessPolicy(new BlobAccessPolicy()
.setStartsOn(OffsetDateTime.now().minusDays(1))
.setExpiresOn(OffsetDateTime.now().plusYears(5))
.setPermissions("r"));
// Throws exception:
containerClient.setAccessPolicy(PublicAccessType.BLOB, Collections.singletonList(identifier));
}
This code fails with:
com.azure.storage.blob.models.BlobStorageException: Status code 403,
"AuthorizationFailureThis
request is not authorized to perform this operation.
RequestId:e5bedc3a-001e-0070-1c70-3981ba000000
Time:2020-06-03T06:29:42.6683502Z"
com.azure.storage.blob.models.BlobStorageException: Status code 403,
"AuthorizationFailureThis
request is not authorized to perform this operation.
RequestId:e5bedc3a-001e-0070-1c70-3981ba000000
Time:2020-06-03T06:29:42.6683502Z" at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at
com.azure.core.http.rest.RestProxy.instantiateUnexpectedException(RestProxy.java:357)
at
com.azure.core.http.rest.RestProxy.lambda$ensureExpectedStatus$3(RestProxy.java:400)
at
reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118)
at
reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1592)
at
reactor.core.publisher.MonoProcessor.onNext(MonoProcessor.java:317)
at
reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1592)
at
reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:144)
at
reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)
at
reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1592)
at
reactor.core.publisher.MonoProcessor.subscribe(MonoProcessor.java:383)
at
reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at
reactor.core.publisher.Mono.subscribe(Mono.java:4087) at
reactor.core.publisher.MonoProcessor.add(MonoProcessor.java:457)
I've created a SAS that is very allowing - but I still get this issue.
using the old SDK it works fine. I've googled for a day - but I can't find any documentation what the SAS permissions should be to make a BLOB public readable.
Changing it manually in the azure portal works fine - but we need to be able to do through code.

Bing translator exception while integrating with java application

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.

Get X509Certificates from smart card without authentication

I want to retrieve the list of X509Certificate from my smart card without logging in (without PIN).
My code is the following:
String conf = args[0];
Provider p = new sun.security.pkcs11.SunPKCS11(conf);
Security.addProvider(p);
KeyStore ks = KeyStore.getInstance("PKCS11");
1) ks.load(null, null);
2) ks.load(null, "".toCharArray());
The first test (1) fails with this StackTrace:
Exception in thread "main" java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:763)
at java.security.KeyStore.load(Unknown Source)
at TestPKCS11.main(TestPKCS11.java:29)
Caused by: javax.security.auth.login.LoginException: no password provided, and n
o callback handler available for retrieving password
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1184)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:849)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:751)
The second (2) fails with:
Exception in thread "main" java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:763)
at java.security.KeyStore.load(Unknown Source)
at TestPKCS11.main(TestPKCS11.java:30)
Caused by: javax.security.auth.login.LoginException
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1238)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:849)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:753)
... 2 more
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_PIN_INVALID
at sun.security.pkcs11.wrapper.PKCS11.C_Login(Native Method)
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1222)
My config is the following:
name=SmartCard
slotListIndex = 0
library=C:\gclib.dll
attributes(*,CKO_PUBLIC_KEY,*)={ CKA_TOKEN=true }
NB: I have a local tool (Classic Client ToolBox) that does not require the PIN to display the certificates.
Looks like Sun's provider always calls Login, no matter if you want to login or not. Frankly speaking, it can be that the only option is to change the approach, e.g. use some other way to access PKCS#11 devices (we have such mechanisms in our SecureBlackbox, for example).
On the other hand, possibility to retrieve information without logging in to the device, is a kind of information leak, and as such possibility to obtain the list or the certificates themselves depends on the particular device. What works on your device might not work on other devices.

How to diagnose "org.restlet.data.Parameter cannot be cast to org.restlet.data.Header" error in Restlet 2.3.5?

I'm using Restlet 2.3.5 in my application. When the GET request handler of a certain server resource is invoked, I get the following error:
[10:26:04] [Restlet-860541310/WARN]: Nov 29, 2015 10:26:04 AM org.restlet.engine.adapter.ServerAdapter addResponseHeaders
WARNING: Exception intercepted while adding the response headers
java.lang.ClassCastException: org.restlet.data.Parameter cannot be cast to org.restlet.data.Header
at org.restlet.engine.header.HeaderUtils.addExtensionHeaders(HeaderUtils.java:226)
at org.restlet.engine.header.HeaderUtils.addResponseHeaders(HeaderUtils.java:653)
at org.restlet.engine.adapter.ServerAdapter.addResponseHeaders(ServerAdapter.java:83)
at org.restlet.engine.adapter.ServerAdapter.commit(ServerAdapter.java:184)
at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:144)
at org.restlet.engine.connector.HttpServerHelper$1.handle(HttpServerHelper.java:64)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:677)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:649)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
The problem is that this exception is thrown outside of the code that I wrote (I added logging statements in my server resource and according to them, the exception is thrown somewhere else).
As a result, I get 500 response (internal server error), even though my server resource sends correct data back to the client.
How can I find out, what exactly is causing this error?
This could be caused when trying to add custom headers in Restlet. When initializing the corresponding map, you would use a map (Series in Restlet) of Parameter instead of Header...
You can use something like that:
Series<Header> responseHeaders = (Series<Header>)
response.getAttributes().get(HeaderConstants.ATTRIBUTE_HEADERS);
if (responseHeaders == null) {
responseHeaders = new Series(Header.class);
response.getAttributes().put(
HeaderConstants.ATTRIBUTE_HEADERS, responseHeaders);
}
responseHeaders.add(new Header("X-MyHeader", "value"));
Hope it helps you,
Thierry

Categories