Not found exception when executing request in service account - google-calendar-api

I get the following error when retrieving the events of my calendar using service account.
Can anyone tell me what I'm doing wrong.
Google.Apis.Requests.RequestError Not Found [404]Errors [Message[Not Found] Location[ - ] Reason[notFound] Domain[global]]
//file path
string GoogleOAuth2CertificatePath = Server.MapPath("GoogleStore\My Project-a725fb0190fc.p12");
// #developer... e-mail address.
string GoogleOAuth2EmailAddress = "939544675132-compute#developer.gserviceaccount.com";
// certificate password ("notasecret").
string GoogleOAuth2PrivateKey = "notasecret";
X509Certificate2 certificate = new X509Certificate2(GoogleOAuth2CertificatePath, GoogleOAuth2PrivateKey, X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(GoogleOAuth2EmailAddress)
{
Scopes = new[] { CalendarService.Scope.Calendar }
}.FromCertificate(certificate));
// Create the service.
service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
ListRequest request = service.Events.List(calID);
request.ShowDeleted = false;
request.SingleEvents = true;
events = request.Execute();
Thank you for any answer what can help me.

Usually when encountering 404: Not found the specified resource was not found. This can happen in several cases.
when the requested resource has never existed.
when accessing a calendar that the user can not access.
Based on the Official Google Documentation, the suggested action is to implement exponential backoff.
Exponential backoff is a standard error handling strategy for network applications in which the client periodically retries a failed request over an increasing amount of time. If a high volume of requests or heavy network traffic causes the server to return errors, exponential backoff may be a good strategy for handling those errors. Conversely, it is not a relevant strategy for dealing with errors unrelated to rate-limiting, network volume or response times, such as invalid authorization credentials or file not found errors.
Used properly, exponential backoff increases the efficiency of bandwidth usage, reduces the number of requests required to get a successful response, and maximizes the throughput of requests in concurrent environments.
Take note that in every request, your application sends to the Google Calendar API must include an authorization token. The token also identifies your application to Google.
Here's a related SO ticket encountered 404 not found error: Error 404 when creating a calendar with Google Calendar Api v3 using c# .net

Related

BizTalk 2016: How to use HTTP Send adapter with API token

I need to make calls to a rest API service via BizTalk Send adapter. The API simply uses a token in the header for authentication/authorization. I have tested this in a C# console app using httpclient and it works fine:
string apiUrl = "https://api.site.com/endpoint/<method>?";
string dateFormat = "dateFormat = 2017-05-01T00:00:00";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("token", "<token>");
client.DefaultRequestHeaders.Add("Accept", "application/json");
string finalurl = apiUrl + dateFormat;
HttpResponseMessage resp = await client.GetAsync(finalurl);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
var rootresult = JsonConvert.DeserializeObject<jobList>(result);
return rootresult;
}
else
{
return null;
}
}
however I want to use BizTalk to make the call and handle the response.
I have tried using the wcf-http adapter, selecting 'Transport' for security (it is an https site so security is required(?)) with no credential type specified and placed the header with the token in the 'messages' tab of the adapter configuration. This fails though with the exception: System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
I have tried googling for this specific scenario and cannot find a solution. I did find this article with suggestions for OAUth handling but I'm surprised that even with BizTalk 2016 I still have to create a custom assembly for something so simple.
Does anyone know how this might be done in the wcf-http send adapter?
Yes, you have to write a custom Endpoint Behaviour and add it to the send port. In fact with the WCF-WebHttp adapter even Basic Auth doesn't work so I'm currently writing an Endpoint Behaviour to address this.
One of the issues with OAuth, is that there isn't one standard that everyone follows, so far I've had to write 2 different OAuth behaviours as they have implemented things differently. One using a secret and time stamp hashed to has to get a token, and the other using Basic Auth to get a token. Also one of them you could get multiple tokens using the same creds, whereas the other would expire the old token straight away.
Another thing I've had to write a custom behaviour for is which version of TLS the end points expects as by default BizTalk 2013 R2 tries TLS 1.0, and then will fail if the web site does not allow it.
You can feedback to Microsoft that you wish to have this feature by voting on Add support for OAuth 2.0 / OpenID Connect authentication
Maybe someone will open source their solution. See Announcement: BizTalk Server embrace open source!
Figured it out. I should have used the 'Certificate' for client credential type.
I just had to:
Add token in the Outbound HTTP Headers box in the Messages tab and select 'Transport' security and 'Certificate' for Transport client credential type.
Downloaded the certificate from the API's website via the browser (manually) and installed it on the local servers certificate store.
I then selected that certificate and thumbprint in the corresponding fields in the adapter via the 'browse' buttons (had to scroll through the available certificates and select the API/website certificate I was trying to connect to).
I discovered this on accident when I had Fiddler running and set the adapter proxy setting to the local Fiddler address (http://localhost:8888). I realized that since Fiddler negotiates the TLS connection/certificate (I enabled tls1.2 in fiddler) to the remote server, messages were able to get through but not directly between the adapter and the remote API server (when Fiddler WASN'T running).

i have a error 401 with microsoft emotion api in java

im using the example code to call the emotions api but i have an error 401 and i cannot identify the error
the result: { "error": { "code": "Unauthorized", "message": "Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key." } }
HttpClient cliente = HttpClients.createDefault();
String key ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
try{
URIBuilder builder= new URIBuilder("https://api.projectoxford.ai/emotion/v1.0/recognize");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-type","application/json");
request.setHeader("Opc-Apim-Subscription-Key",key);
StringEntity reqEntity = new StringEntity("\"url\": \"http://am-elsalv-cdn.agilecontents.com/resources/jpg/5/3/1458595472835.jpg\"");
request.setEntity(reqEntity);
HttpResponse response = cliente.execute(request);
HttpEntity entity = response.getEntity();
if(entity!=null){
System.out.println(EntityUtils.toString(entity));
}
}catch(Exception e){
System.out.println(e.getMessage());
}
The 401 error is typically shown when you’re using an invalid subscription key to call our APIs. This could happen for a number of reasons:
Incorrect key as result of a copy/Paste error when pulling the key from http://www.microsoft.com/cognitive-services/en-us/subscriptions. Additionally, make sure there are no leading or trailing spaces in your key (it doesn’t look like it from your code, but calling out for completeness).
If your key was working before and now is no longer working, you could be out of your monthly quota (number of calls) or trying to make calls too quickly for the TPS (transactions per second) supported for your key. You can check the status of your key by going to the subscriptions page, finding the emotion subscription, and clicking “Show quota”.
There is a service interruption currently on-going. If you think this is the case, please let us know through tickets#cognitive.uservoice.com.
If you’ve tried all of these things and are still experiencing issues, try to make an API call using your subscription key through our testing console. If this still fails, regenerate your key through the subscriptions page by finding the Emotion API, identify the key column, and clicking “Regenerate” under the key that is not working. Note that you’ll have to update all references to your old key as this will completely invalidate it in favor of the newly generated key.

Get token from ADFS

I'm trying to obtain a token from ADFS to that I can use it with an on-premise Windows Service Bus installation. I may not have ADFS properly configured because I get the following message:
MSIS3127: The specified request failed.
The code to access the token is as follows:
string adrecaSTS = "trust/13/usernamemixed";
WS2007HttpBinding binding = new WS2007HttpBinding();
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.TransportWithMessageCredential; //https
string baseSSLUri = #"https://<myadfs>/adfs/services/";
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(baseSSLUri + adrecaSTS));
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
trustChannelFactory.Credentials.UserName.UserName = "username";
trustChannelFactory.Credentials.UserName.Password = "password";
WSTrustChannel tokenClient = (WSTrustChannel)trustChannelFactory.CreateChannel();
//create a token issuance issuance
RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue);
//call ADFS STS
SecurityToken token = tokenClient.Issue(rst);
The endpoint is enabled on ADFS and my client (laptop on separate domain) trusts the certificate from ADFS.
Do I need to set up some kind of trust or something further? This error message is not particularly helpful.
See here:
https://github.com/thinktecture/Thinktecture.IdentityServer.v2/blob/master/src/Libraries/Thinktecture.IdentityServer.Protocols/WSFederation/HrdController.cs
The ValidateToken method has most of the code - but you first need to extract the InnerXml from the generic token and turn that into a SAML security token (again using a token handler).
Found the issue. I was trying to log on as an administrator account. When I used a regular user it worked.
I also had to modify the RequestSecurityToken to have a KeyType of KeyType.Symmetric
I see that you solved your issue, but here is some additional inforamation to potentially help others that might have the same error message but a different cause.
The AD FS error, "MSIS3127...", can have multiple causes. For us, it was caused by one of our relying party claim rules specifying an AD FS attribute store that didn't exist.
In order to debug the error, we checked the Event Viewer on all of the servers running AD FS, and that's where we found the detailed message that called out the attribute store problem. So, if anyone else gets the same error message, then I suggest checking the Event Viewer on AD FS to see if there are additional logs.
Note that AD FS logs to the Event Viewer under the folder/node of Applications and Services Logs => AD FS => Admin

Asp.net and OAuth simple example without existing Library

I try to get a request token from Twitter OAuth and I always received a server error 401 when I try to get the response. I don't want to used an existing library because I try to learn Oauth and maybe build my own library. This is my simple code :
WebRequest request = WebRequest.Create("https://api.twitter.com/oauth/request_token");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
StringBuilder sbParams = new StringBuilder();
sbParams.Append("OAuth ");
sbParams.AppendFormat("oauth_consumer_key={0},", "[COMSUMERKEY]");
sbParams.AppendFormat("oauth_signature_method={0},", "PLAINTEXT");
sbParams.AppendFormat("oauth_signature={0},", HttpUtility.UrlEncode("[COMSUMER_SECRET]&"));
sbParams.AppendFormat("oauth_timestamp={0},", ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds).ToString());
sbParams.AppendFormat("oauth_nonce={0},", "asdfalkjpoijwpeonpoaisudfnpowieuyfpasosdfdn");
sbParams.AppendFormat("oauth_version={0},", "1.0");
sbParams.AppendFormat("oauth_callback={0}", HttpUtility.UrlEncode(Request.Url.ToString()));
request.Headers.Add("Authorization", sbParams.ToString());
// Get the response.
WebResponse response = request.GetResponse();
From http://oauth.net/core/1.0a/#http_codes You know these
HTTP 401 Unauthorized
Invalid Consumer Key
Invalid / expired Token
Invalid signature
Invalid / **used nonce
The "used nonce" thing may be a problem. You need to generate a random string. From http://oauth.net/core/1.0a/#nonce
A nonce is a random string, uniquely generated for each request
Onto the serious business. You are not supposed to transmit your consumer secret, once you ever received it! Many OAuth libraries have a
request_request_token(consumer_key,consumer_secret)
Despite appearances, the consumer_secret is never transmitted. It is used at client-side, for verification of server's response. (A similar verification occurs at server-side too)
And you dont put in any static values for signing requests. From http://oauth.net/core/1.0a/#signing_process
All Token requests and Protected Resources requests MUST be signed by the Consumer and verified by the Service Provider.
Bottomline: do read the http://oauth.net/core/1.0a/ article to see how the protocol works. And choose a hands-on OAuth library that doesnt abstract too much details (The oauth-php library I used came with SQL tables and managed data stores and session memory by itself).

Login error connecting to salesforce.com from Flex

Has anyone suddenly encountered login errors from their users trying to connect to salesforce.com from a Flex app using as3salesforce.swc?
I get the following error... password removed to protect the innocent...
App Domain = null
Api Server name = na3.salesforce.com
_internalServerUrl = https://na3.salesforce.com/services/Soap/u/14.0
loading the policy file: https://na3.salesforce.com/services/Soap/cross-domain.xml
Your application must be running on a https server in order to use https to communicate with salesforce.com!
login with creds
loading the policy file: https://na3.salesforce.com/services/crossdomain.xml
Your application must be running on a https server in order to use https to communicate with salesforce.com!
invoke login
intServerUrl is null
intServerUrl = https://na3.salesforce.com/services/Soap/u/14.0
_invoke login
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer set destination to 'DefaultHTTPS'.
Method name is: login
'direct_http_channel' channel endpoint set to http://localhost/pm_server/pm/
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer sending message 'E32C7199-72C1-B258-B483-FFBC1641173D'
'direct_http_channel' channel sending message:
(mx.messaging.messages::HTTPRequestMessage)#0
body = "<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/"><se:Header xmlns:sfns="urn:partner.soap.sforce.com"/><se:Body><login xmlns="urn:partner.soap.sforce.com" xmlns:ns1="sobject.partner.soap.sforce.com"><username>simon.palmer#dialectyx.com</username><password>******</password></login></se:Body></se:Envelope>"
clientId = (null)
contentType = "text/xml; charset=UTF-8"
destination = "DefaultHTTPS"
headers = (Object)#1
httpHeaders = (Object)#2
Accept = "text/xml"
SOAPAction = """"
X-Salesforce-No-500-SC = "true"
messageId = "E32C7199-72C1-B258-B483-FFBC1641173D"
method = "POST"
recordHeaders = false
timestamp = 0
timeToLive = 0
url = "https://na3.salesforce.com/services/Soap/u/14.0"
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer connected.
Method name is: login
Error: Ignoring policy file at https://na3.salesforce.com/crossdomain.xml due to meta-policy 'by-content-type'.
'5A5D3012-7717-E3C2-9B39-FFBBFF1F1B47' producer acknowledge of 'E32C7199-72C1-B258-B483-FFBC1641173D'.
responseType: Fault
Saleforce Soap Fault: sf:INVALID_LOGIN
INVALID_LOGIN: Invalid username, password, security token; or user locked out.
Comunication Error : sf:INVALID_LOGIN : INVALID_LOGIN: Invalid username, password, security token; or user locked out. : [object Object]
Obviously nobody else out there is building Flex apps on top of salesforce.com..
yippee, I'm first.
Anyhow, I just found out that this is a bug at salesforce.com as at 6th December 2008. The issue is that the scripts which handle login do not cope adequately with the redirect necessary because of load balancing on the salesforce.com servers.
It should be possible to go through the www front door of salesforce.com's api with a URL such as...
"https://www.salesforce.com/services/Soap/u/13.0";
where the 13 represents the version of their API you are targetting. However, all users are actually assigned to a specific server, so the front door should redirect the login request to the approriate place, and it doesn't if you are coming from Flex.
A workround is to specify your server in the URL, such as...
"https://na5.salesforce.com/services/Soap/u/13.0";
...which is what I was doing. That's fine if you are a single user accessing the same resources continually and your account remains attached to that server. However if...
You are distributing your app so anyone who has a salesforce.com enterprise account can log in OR
Your account gets moved because of some internal load balancing (which is what happened to me)
then the approach of providing a fixed server won't work.
The bug (as far as I understand it) is that the www route doesn't adequately redirect to your host server. Last intelligence was that it will be fixed "soon".
I wish I could mark this as the answer...

Resources