Xamarin.Auth doesn't work with Linkedin V2 API - xamarin

I'm actually trying to do a simple login with Linkedin and the new API V2 with Xamarin.Auth extension. I do get the token like this
var auth = new OAuth2Authenticator(
clientId: *****,
clientSecret: *****,
scope: "r_liteprofile",
authorizeUrl: new Uri("https://www.linkedin.com/oauth/v2/authorization"),
redirectUrl: new Uri(*****),
accessTokenUrl: new Uri("https://www.linkedin.com/oauth/v2/accessToken")
);
but when I try to make a request it fails with an {"serviceErrorCode":100,"message":"Unpermitted fields present in PARAMETER: Data Processing Exception while processing fields [/access_token, /format]","status":403}. Code for these error:
var request = new OAuth2Request(
"GET",
new System.Uri("https://api.linkedin.com/v2/me?"
+ "format=json"
+ "&oauth2_access_token="
+ e.Account.Properties["access_token"]),
null,
e.Account
);
var linkedinResponse = await request.GetResponseAsync();
var json = linkedinResponse.GetResponseText();
Console.WriteLine(json);
If I take out the fields, it fails because of empty access token: {"serviceErrorCode":65604,"message":"Empty oauth2 access token","status":401} Code for these error:
var request = new OAuth2Request(
"GET",
new System.Uri("https://api.linkedin.com/v2/me"),
null,
e.Account
);
var linkedinResponse = await request.GetResponseAsync();
var json = linkedinResponse.GetResponseText();
Console.WriteLine(json);
I've confirmed that I've recieved the token. Looking for a solution I found that the token must be in a header but I can't change or add any header. Can anyone help me please?
Thank you very much.
PD: Forgot to say this code is for Android but I needed to do it for iOS aswell.

Hi finally I found the solution to this.
In Linkedin API V2 you have to change your AccessTokenparameterName.
yourOauth2Request.AccessTokenParameterName = "oauth2_access_token";
Hope I can help somebody to not get mad like me.

Related

Get OAuth 2.0 token for google service accounts

Short explanation
I want to get a Auth2.0 token for access to some APIs in my Google Cloud Platform proyect.
Context
At the current time i have a Wordpress page that has to make the connection. Temporarily i will make a javascript connection with the client via Ajax (when all work successfully i will make this in another way, for example with a PHP server in the middle).
The process that has to execute in our GCP don't need the user to log in with his google account, for that reason we will make a google service account for server to server connections. All the threads executed by the API will be log like be executed by this service account that isn't owned by any real person.
When i generate the Ajax connection for get the token, this will be send to the following URL:
https://oauth2.googleapis.com/token
I send it on JWT coding.
The coded message is generated in this Javascript code:
`
var unixHour = Math.round((new Date()).getTime() / 1000);
var header = {
"alg":"RS256",
"typ":"JWT"
}
var data = {
"iss":"nombreoculto#swift-firmament-348509.iam.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/devstorage.read_only",
"aud":"https://oauth2.googleapis.com/token",
"exp":(unixHour+3600),
"iat":unixHour
}
var secret = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCkhZH7TuaNO4XBVVVcE2P/hvHSsGXNu1D/FcCaMrW56BF/nbOlxAtbp07TCIOyrR1FEcJb+to66olSFnUVUWhWUB9zLbzKpULQoFmYECSWppUbCZd+bp271AFYZpxXFduziWuaG9BNxV2cmWTjLLlZI7FoIYFwLgPZHPWndY0E99lGEjmnH";
function base64url(source) {
// Encode in classical base64
encodedSource = CryptoJS.enc.Base64.stringify(source);
// Remove padding equal characters
encodedSource = encodedSource.replace(/=+$/, '');
// Replace characters according to base64url specifications
encodedSource = encodedSource.replace(/\+/g, '-');
encodedSource = encodedSource.replace(/\//g, '_');
return encodedSource;
}
var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
var encodedHeader = base64url(stringifiedHeader);
//document.getElementById("header").innerText = encodedHeader;
console.log(encodedHeader);
var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
var encodedData = base64url(stringifiedData);
//document.getElementById("payload").innerText = encodedData;
console.log(encodedData);
var signature = encodedHeader + "." + encodedData;
signature = CryptoJS.HmacSHA256(signature, secret);
signature = base64url(signature);
console.log(signature);
//document.getElementById("signature").innerText = signature;
var jwt = encodedHeader + "." + encodedData + "." + signature;
console.log(jwt);
$.ajax({
url: 'https://oauth2.googleapis.com/token',
type: 'POST',
data: { "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion" : jwt} ,
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
success: function (response) {
alert(response.status);
},
error: function () {
alert("error");
}
});
`
Console:
Console output
The problem
The Ajax message generated in the script return "Invalid JWT signature".
send message API
ajax response API
Following the google documentation, this problem is for a bad coding of the message or a incorrect secret key.
You can see the code for generate the coding message in the previous script.
About the secret key, maybe i am not selecting the correct key for this task, here you have the steps i follow:
cred GCP
Inside the service account, i create a key in the "keys" section:
Keys GCP
As result this download this file:
File keys
I tried to use like secret key the "private_key" content of this file and additionally i tried to delete the line breaks (\n) of this and try again.
¿Is that correct?¿Or i dont use the corret key?
¿Maybe i make an incorrect coding?
*There aren't problems with share the key and account id because the key was disabled at the moment of share this thread and the project is only for testing purposes.

Stripe returns a "No such token" error (Plaid Integration)

I am getting this error from Stripe when I try to create a new source for the selected bank account. I am using the new (beta) version of the Plaid Node SDK. Here is my code:
let user;
const mode = "sandbox";
const dsService = new CaspioDsService();
// Load the user if not already loaded by cognitoAuth
if (!req.user) {
user = new User(
dsService,
new CaspioRefDataService(),
new AuthUserService({
organizationId: res.locals.organization.Organization_ID,
isAuthenticated: res.locals.isAuthenticated,
})
);
await user.load(req.params.userId);
} else {
user = req.user.userObject;
}
const configuration = new Configuration({
basePath: PlaidEnvironments[mode],
baseOptions: {
headers: {
"PLAID-CLIENT-ID": config.plaid.clientId,
"PLAID-SECRET": mode === "sandbox" ? config.plaid.secretSandbox : config.plaid.secretProduction,
"Plaid-Version": "2020-09-14",
},
},
});
const plaidClient = new PlaidApi(configuration);
console.log(configuration.basePath); // https://sandbox.plaid.com
// Exchange the public token for the Plaid access token
const plaidTokenRes = await plaidClient.itemPublicTokenExchange({
public_token: req.body.publicToken,
});
const accessToken = plaidTokenRes.data.access_token;
console.log(accessToken); // access-sandbox-d92396c2-1f49-4780-9ae9-23d50645f364
// Get the Stripe bank account token from Plaid
const stripeTokenRes = await plaidClient.processorStripeBankAccountTokenCreate({
access_token: accessToken,
account_id: req.body.accountId
});
const bankAccountToken = stripeTokenRes.data.stripe_bank_account_token;
console.log(bankAccountToken); // btok_1JFMGwGq7ejZoSiwGmM8WSSm
let stripeCustomerId = user.getStripeToken();
const stripeClient = await StripeHelper.getStripeClient(mode); // Get Stripe client in sandbox mode
console.log(stripeCustomerId); // cus_Jt7AWZjC8rHPzt
// Add the source to the Stripe customer and get the bank account info
const bankAccount = await stripeClient.customers.createSource(stripeCustomerId, {
source: bankAccountToken,
}); // Error: No such token: 'btok_1JFMGwGq7ejZoSiwGmM8WSSm'
Any ideas what I might be doing wrong? I expect the issue is with my code, or possibly Plaid (I don't think it is a Stripe problem).
It sounds like you're getting a token from Plaid, but Stripe is rejecting it, which suggests a problem with the relationship between your Plaid and Stripe setups. Are you sure that you enabled the Plaid/Stripe integration in the Plaid dashboard and that the client id / secret you're using matches the Plaid account where the integration is enabled? The Plaid docs also suggest that this error can be caused by using a mismatched set of environments (e.g. using Production with Stripe but Sandbox with Plaid).
The problem was that we had the wrong Stripe account connected. Silly one, but I'm posting this in case anyone else makes the same mistake.

jwt token in DOTNET WebApi

I literally read the internet through, tried multiple approaches and so on - with no luck.
I am trying to make a pretty small WebApi project with a few controllers protected by a jwt token.
I generate the token using following code:
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("may the force"));
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims.ToArray()),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
I have setup the authentication (in Startup.cs) bits like
services.AddAuthentication(x => {
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}
)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("may the force"))
};
});
Using my AuthController I can generate the Token(first code block in this question) - and the Controllers needed to be "protected" is annotated with [Authorize]
If I take the result from AuthController and paste it at https://jwt.io the signature is valid.
I am testing the controllers using postman and setting the request header Authorization to Bearer <the token>
Can anyone point me in the right direction?
Thanks alot!
UPDATE: I misused the jwt.io site initially, thus some of the comments underneath here are no longer valid.
UPDATE 2: Realized that the server tried to use cookie based authentication. Changing the annotation to [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] made the trick - but still not sure why

OAuth2 client, Completed never called

I am trying to use OAuth2 client of xamarin with facebook, I tried this:
var auth = new OAuth2Authenticator(
clientId: "xxxxxxxxxx",
scope: "",
authorizeUrl: new Uri("https://www.facebook.com/dialog/oauth/"),
redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html"));
auth.Completed += (s, ee) => { .... }
StartActivity(auth.GetUI(this));
However, Completed never called.. Any idea?
After I tested your code and realized that the problem is related to the Facebook App creation, I suggest you to read and follow this.

Request to Parse API using RestSharp.Portable in Xamarin

I'm having problems trying to do a GET request to Parse REST API using RestSharp.Portable in a PCL Xamarin project.
The problem occurs in the line:
var result = await client.Execute (request);
Throwing an exception and stopping the app (Android).
This is the function i'm using.
public async Task<EventItem> GetAListOfAllEvents ()
{
using (var client = new RestClient (new Uri ("http://api.parse.com"))) {
var request = new RestRequest ("1/classes/Event/2yHLWDUlv3");
request.Method = HttpMethod.Get;
request.AddHeader ("Content-Type", "application/json");
request.AddHeader ("X-Parse-Application-Id", "myAppId");
request.AddHeader ("X-Parse-REST-API-Key", "myAPIparseKey");
var result = await client.Execute (request);
return result;
}
}
I hope someone could help me, thanks.
Remove this line.
request.AddHeader ("Content-Type", "application/json");
Request is failing because of it (probably as you have no actual content in your GET request).

Resources