Spreedly authentication error using C#.Net HttpWebRequest: "You must specify an environment_key parameter" - httpwebrequest

I'm currently working with Spreedly REST API which works with basic http authentication.
At first, I set my credentials this way:
webRequest.Credentials = new System.Net.NetworkCredential(user, password);
It worked well for many of the API resources including POSTing new gateways, GETing gateways, PUTing data on a gateway and even redacting a gateway.
I hit a wall when I tried to POST a new payment_method at their /v1/payment_methods.<format> resource.
The error I'm getting:
HTTP 422
{
"errors": [
{
"key": "errors.environment_key_parameter_required",
"message": "You must specify an environment_key parameter."
}
]
}
After verifying a lot of things, I tried it using curl based on their examples and it worked.
The issue seems to be in the way I set my credentials in the HttpWebRequest even though it's the same code I use for the other working resources.
I tried using the CredentialCache because I could specify "Basic" and it failed the same way:
CredentialCache cache = new CredentialCache();
cache.Add(webRequest.RequestUri, "Basic", new System.Net.NetworkCredential(user, password));
webRequest.Credentials = cache;

Here's what worked:
I created my own authorization HTTP header as suggested in https://stackoverflow.com/a/13956730/5869109 and it worked well:
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1")
.GetBytes(user + ":" + password));
webRequest.Headers.Add("Authorization", "Basic " + encoded);

Related

Getting A Refresh Token From Google Using An Authorization Token Posted in Java

I have read many posts, all the Google documentation I can find and tried many iterations of the following and still can't get an access and refresh token. I do get an authorization code but can't seem to get that to trade for the access and refresh tokens.
if(authCode == null || authCode.equals("")) {
String url = "https://accounts.google.com/o/oauth2/v2/auth?"
+ "scope=https://mail.google.com/&"
+ "response_type=code&"
+ "redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&"
+ "client_id=" + clientId +
"&access_type=offline";
URI uri = new URI(url);
logger.debug("URI for auth is: " + uri);
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(uri);
}
}
else {
logger.debug("Refreshing");
initRefreshToken();
}
With that, I get an access code I can cut and paste (just testing and trying to get this to work first) in my properties to get the refresh and access token.
In the initRefreshToken() method, the source is like this:
if(refreshToken.equals("")) {
logger.debug("Getting refresh token");
HttpPost post = new HttpPost("https://oauth2.googleapis.com/token");
// add request parameter, form parameters
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("code", authCode));
urlParameters.add(new BasicNameValuePair("client_id", clientId));
urlParameters.add(new BasicNameValuePair("client_secret", clientSecret));
urlParameters.add(new BasicNameValuePair("redirect_uri", "http://localhost:8000/"));
urlParameters.add(new BasicNameValuePair("grant_type", "authorization_code"));
try {
post.setEntity(new UrlEncodedFormEntity(urlParameters));
System.out.println("***** URL: " + urlParameters);
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(post);
System.out.println(EntityUtils.toString(response.getEntity()));
}
If this is a second or subsequent time using the code, what will be printed is:
Refersh token:
***** URL: [code=4/1AY0e-g..., client_id=370...i1h2u1s.apps.googleusercontent.com, client_secret=bAOH..., redirect_uri=https://localhost:8000/, grant_type=authorization_code]
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
If the code is run and it's the first time using an authentication code, it will print:
{
"error": "redirect_uri_mismatch",
"error_description": "Bad Request"
}
I read in the Google console that exceptions are made for localhost domains so there's no need to register them. However, if there were a need to register them, it won't let you register them anyway as a domain must be a top level domain you own in order to register it. Therefore, how do I register localhost and/or exchange an authorization code for an access and refresh token in Java?
Thank you for your help.
DaImTo provided a great video about this and in that video and the blog post associated with it, the redirect_uri is listed correctly as: "urn:ietf:wg:oauth:2.0:oob". I didn't find this in the documentation but when I added it to my source code, I got access and refresh tokens as a response. Thank you very much for that help, DaImTo.

403 access denied to the website with proper login/pass through google script

var url = "https://web-site_name/page/?format=json&var_data-organization_dates&xlsexport=true";
var payload =
{
"login" : "login",
"password" : "pass",
};
var options =
{
"method" : "post",
"payload" : payload,
"followRedirects" : false
};
var login = UrlFetchApp.fetch("https://web-site_name/page/" , options);
var sessionDetails = login.getAllHeaders()['Set-Cookie'];
Logger.log(login.getAllHeaders());
here is the part of the code I try to use, to automate export of the data from web-site, i do have proper login and password and able to download file in json (opened in xsl) manually, I've got the address to the downloaded file in network in developer tools, but i have a problem on the first stage - when trying to authorize to the web-site - access denied. I've tried the code, given in answers on stackoverflow, but it still doesn't work.
How to make an url fetch request correctly, depends on the website you want to access and the authentication they uses
In the simplest case, your website requires HTTP basic authentification, in this case the correct syntax would be
var authHeader = 'Basic ' + Utilities.base64Encode(login + ':' + pass);
var options = {
headers: {Authorization: authHeader}
}
If your website uses a different authentication form, you might need to provide an access token.
In any case: the authentication credentials go into headers, not into payload!
payload is the data that you want to post = upload to the website.
If you want export data from the website - that is download data - you do not need a payload and the correct method would be get, not post. Btw., if the method is get, you do not need to specify it.
Please see here for more information and samples.

API Connect 5 - Error attempting to read the urlopen response data

I'm trying to create a REST API from a SOAP Service using IBM API Connect 5. I have followed all the steps described in this guide (https://www.ibm.com/support/knowledgecenter/en/SSFS6T/com.ibm.apic.apionprem.doc/tutorial_apionprem_expose_SOAP.html).
So, after dragging the web service block from palette, ensuring the correctness of endpoint and publishing the API, I have tried to call the API from the browser. Unfortunately, the API return the following message:
<errorResponse>
<httpCode>500</httpCode>
<httpMessage>Internal Server Error</httpMessage>
<moreInformation>Error attempting to read the urlopen response
data</moreInformation>
</errorResponse>
To testing purpose, I have logged the request and I have tried the request on SOAPUI. The service return the response correctly.
What is the problem?
In my case, the problem was in the backend charset (Content-Type: text/xml;charset=iso-8859-1).
For example, backend returns text/xml in German (or French). Api Connect cannot process character ü. It needs Content-Type: text/xml;charset=UTF-8.
I had a similar issue, in my case was the accept. if you have an Invoke and the content-type or the accept, is not matching the one of the request, or the response that you got, APIC is getting mad.
Please, check if the formats to send (contentType) and receive (accept) are the same of that your API expected. In my case the error occurs because the API returns a String and my default code is configured to receive a JSON body.
//define a JSON-PLAIN TEXT protocol
private HttpEntity<String> httpEntityWithBody(Object objToParse){
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + "xxx token xxx");
headers.set("Accept", MediaType.TEXT_PLAIN_VALUE);
headers.setContentType(MediaType.APPLICATION_JSON);
Gson gson = new GsonBuilder().create();
String json = gson.toJson(objToParse);
HttpEntity<String> httpEntity = new HttpEntity<String>(json, headers);
return httpEntity;
}
//calling the API to APIC...
ParameterizedTypeReference<String> responseType = new
ParameterizedTypeReference<String>(){};
ResponseEntity<String> result =
rest.exchange(builder.buildAndExpand(urlParams).toUri(), HttpMethod.PUT, httpEntityWithBody(myDTO), responseType);
String statusCode = result.getStatusCodeValue();
String message = result.getBody();

BadRequest when try Create folder via REST

I've downloaded a exampled that show the files in the "Shared with everyone" folder in my OneDrive for Bussiness. It's work fine!
But, when I try to create a Folder or File (without content) like this documentation the response became with a BadRequest .
The request goes like:
string requestUrl = String.Format(CultureInfo.InvariantCulture, "{0}/files", serviceInfo.ApiEndpoint);
// Prepare the HTTP request:
using (HttpClient client = new HttpClient())
{
Func<HttpRequestMessage> requestCreator = () =>
{
HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Post, requestUrl);
request.Headers.Add("Accept", "application/json;odata.metadata=full");
request.Content = new StringContent(#"{'__metadata':{'type':'MS.FileServices.Folder'},Name:'TestFolder'}");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return request;
};
}
And the response is a BadRequest.
I think that my problem is in the "__metadata"'s json value. It´s is correct? Where can I find a working example implementing this operations?
Thanks in advance!
EDIT: Changing the API Endpoint from "/_api/web/getfolderbyserverrelativeurl('Documents')/files" to "_api/files" the error became to: "The property '__metadata' does not exist on type 'MS.FileServices.FileSystemItem'. Make sure to only use property names that are defined by the type."
I´m think I foward in this. But, I still continue with problems.
I am not sure if this can be of any help to you, as this pertains to oneDrive and not oneDrive for business.
Also the documentations are confusing :)
according to the documentation the request should be as follow:
POST https://apis.live.net/v5.0/me/skydrive
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"name": "My example folder"
}
if you can see that in the header there is authorization access token
I don't see that you sent to the server any access token. and that is why you had a bad request.
I am trying to below way to create a folder in SP and it's working for me. Hope it will work for you as well.
Create a folder using SharePoint Web API -
POST https://<Domain>.sharepoint.com/_api/web/folders
Accept: "application/json;odata=verbose"
Content-Type: "application/json"
{
"ServerRelativeUrl": "/Shared Documents/<Folder-Name>"
}

Linkedin token not valid

Here is a strange thing I am fighting against.
First of all I am using this simple-linkedinphp lib to perform API calls from my php backend.
I got a user access token from our IOS app which has the following structure:
{"access_token":"lettersAndSymbols","expires_in":5183999}
I store it in a variable called $token.
Then I try to get the user's profile with this token like this:
$linkedin = new \LinkedIn($this->linkedin_config);
$linkedin->setResponseFormat($linkedin::_RESPONSE_JSON);
$linkedin->setTokenAccess(array('oauth_token' => $token["access_token"], 'oauth_token_secret' => ""));
$linkedinUserJson = $linkedin->profile("~");
Then I get the response with error:
array(5) {
["linkedin"]=>
string(358) "{
"errorCode": 0,
"message": "[unauthorized]. The token used in the OAuth request is not valid. sameLettersAndSymbols",
"requestId": "74T6SY6ML6",
"status": 401,
"timestamp": 1376043937705
}
But when I try to open an api url in a browser with the same LettersAndSymbols like https://api.linkedin.com/v1/people/~?oauth2_access_token=LettersAndSymbols, I get the correct response with user object.
How can that be? Am I doing something wrong with the API lib?
I can see a problem in this line
$linkedin->setTokenAccess(array('oauth_token' => $token["access_token"], 'oauth_token_secret' => ""));
your must provide a secret to set the token access.
I found a nice example about Linkedin Integration, wich I like to share with you, I tested and it works just fine.
How to Integrate login with LinkedIn oAuth in PHP