email_verified = false in ID token from Google - jwt

I use Google ID tokens to sign in users to my webservice. As part of validating the token it receives from Google, the webservice checks that email_verified = true in the token's payload.
Some of my users signed up for a Google-account with their non-Gmail, non-Google Apps email address. They did click the link in the email that Google sent them after sign-up, to verify their email address.
When those users try to login to my webservice, I get email_verified = false in the token's payload.
What does this mean and can/ should I ignore this in validating the token?

There are a couple of different ways in which you can validate the integrity of the ID token on the server side:
"Manually" - constantly download Google's public keys, verify signature and then each and every field, including the iss one; the main advantage (albeit a small one in my opinion) I see here is that you can minimize the number of requests sent to Google.
"Automatically" - do a GET on Google's endpoint to verify this token
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
Using a Google API Client Library - like the official one.
Here's how this could look:
private const string GoogleApiTokenInfoUrl = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}";
public ProviderUserDetails GetUserDetails(string providerToken)
{
var httpClient = new MonitoredHttpClient();
var requestUri = new Uri(string.Format(GoogleApiTokenInfoUrl, providerToken));
HttpResponseMessage httpResponseMessage;
try
{
httpResponseMessage = httpClient.GetAsync(requestUri).Result;
}
catch (Exception ex)
{
return null;
}
if (httpResponseMessage.StatusCode != HttpStatusCode.OK)
{
return null;
}
var response = httpResponseMessage.Content.ReadAsStringAsync().Result;
var googleApiTokenInfo = JsonConvert.DeserializeObject<GoogleApiTokenInfo>(response);
if (!SupportedClientsIds.Contains(googleApiTokenInfo.aud))
{
Log.WarnFormat("Google API Token Info aud field ({0}) not containing the required client id", googleApiTokenInfo.aud);
return null;
}
return new ProviderUserDetails
{
Email = googleApiTokenInfo.email,
FirstName = googleApiTokenInfo.given_name,
LastName = googleApiTokenInfo.family_name,
Locale = googleApiTokenInfo.locale,
Name = googleApiTokenInfo.name,
ProviderUserId = googleApiTokenInfo.sub
};
}

Related

How can I get "Amazon.Extensions.CognitoAuthentication.CognitoUserSession.IDToken" From AWSCredentials?

I want get "Amazon.Extensions.CognitoAuthentication.CognitoUserSession.IDToken" From AWSCredentials.
I have AWSCredentials From Oauth Google Login.
public AWSCredentials GetAWSCredentials_Google(string token)
{
CognitoAWSCredentials credentials = new CognitoAWSCredentials(FED_POOL_ID, regionTable[REGION]);
credentials.AddLogin("accounts.google.com", token);
return credentials;
}
And, I use EC2 Instance and my ubuntu server is in there. Also, I was originally using a method of accessing the server by receiving a membership from Cognito User Pool, so I was using the following code.
private IEnumerator sendPostUser()
{
string uri = rootUrl + "/user";
string json = "{ ... }";
byte[] jsonData = System.Text.Encoding.UTF8.GetBytes(json);
using (UnityWebRequest request = UnityWebRequest.Post(uri, json))
{
if (request.uploadHandler != null)
request.uploadHandler.Dispose();
request.disposeUploadHandlerOnDispose = true;
request.disposeDownloadHandlerOnDispose = true;
request.uploadHandler = new UploadHandlerRaw(jsonData);
/* Header */
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("token", cloud_acess.GetComponent<ControlCloud>().cognitoUser.SessionTokens.IdToken);
/* Send Message */
yield return request.SendWebRequest();
...
}
By the way, there was a problem with this code "request.SetRequestHeader("token", cloud_acess.GetComponent().cognitoUser.SessionTokens.IdToken);".
This cognitouser means Amazon.Extensions.CognitoAuthentication.CognitoUser.
My Project get CognitoUser using user's ID and PW, and get AWSCredentials using this Cognitouser. But Google Login doesn't this process and just get credentials.
So, I can't get "cognitoUser.SessionTokens.IdToken". It makes me cannot to request anything from ec2 server.
How Can i get this? What should I do if the premise of this problem itself is wrong?
I tried to put all the tokens I received when I logged in to Google and the tokens I received as credentials in the header.But I failed.

Is there any way to add tracking info on behalf of the clients?

Is there any way to add tracking info fields on behalf of other clients using the new REST API?
If not, can I still create paypal apps that use the old API, or any other way?
There is an old Question that demonstrates what I am trying to do.
By following this Documentation page I managed to update info on my sandbox account using the following C# code...
private static string SendRequest()
{
var client = new HttpClient();
var end_point = "https://api.sandbox.paypal.com/v1/shipping/trackers-batch";
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
var requestMessage = new HttpRequestMessage
{
RequestUri = new Uri(end_point),
Method = HttpMethod.Post,
};
string clientId = "";
string secret = "";
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes($"{clientId}:{secret}")));
string body = File.ReadAllText("data.json");
requestMessage.Content = new StringContent(body, Encoding.UTF8, "application/json");
var x = client.SendAsync(requestMessage).Result;
string responseStr = x.Content.ReadAsStringAsync().Result;
return responseStr;
}
catch (Exception exp)
{
Debug.Print(exp.Message);
return null;
}
finally
{
client.Dispose();
}
}
data.json
{
"trackers": [
{
"transaction_id": "04YE27.....",
"tracking_number": "443844....",
"status": "SHIPPED",
"carrier": "FEDEX"
}
]
}
But it fails to update another SandBox account data even when I granted the permissions from that account settings to my app. This is the server response:
{
"tracker_identifiers":[
],
"errors":[
{
"name":"NOT_AUTHORIZED",
"message":"Authorization failed due to insufficient permissions",
"details":[
{
"field":"/trackers/1/transaction_id",
"value":"04YE27.....",
"location":"body",
"issue":"USER_NOT_AUTHORIZED",
"description":"You are not authorized to add or modify tracking number for this transaction"
}
],
"links":[
]
}
],
"links":[
{
"href":"https://api.sandbox.paypal.com/v1/shipping/trackers-batch",
"rel":"self",
"method":"POST",
"encType":"application/json"
}
]
}
I can ask the users to give the required permissions to my app. but I can't ask everyone to create an app and give me their Client ID and secret.
I can't ask everyone to create an app and give me their Client ID and secret.
This is exactly what you need to do to have this level of granular control over transaction-level information in their PayPal account.
Besides creating an app for you and sharing its credentials, there isn't a mechanism for them to grant the permission.
If not, can I still create paypal apps that use the old API, or any other way?
The old APIs and apps do not offer a way to update tracking information. They also aren't supported for new integrations, and should no longer be used (backwards compatibility/maintenance only)

How to call Windows Azure Storage RestFul Service without SDK?

I try to use Windows Azure like a Storage fom Salesforce.com.
I cheked the documentation and I only can see call the calls to azure rest api from SDK (Java, .Net, JS, etc) examples.
I need integrate Salesforce with Windows Azure Storage but, Azure don't have a SDK for Salesforce.com
From Salesforce.com is allow the calls to rest services but the process to call Azure Rest Services require one o more librarys.
Exameple:
Authentication for the Azure Storage Services require of:
Headers: Date Header and Authorization Header
The Authorization Header require two elments
SharedKey
Account Name
Authorization="[SharedKey|SharedKeyLite] :"
SharedKey and Account Name give a conversion:
HMAC-SHA256 conversion
over UTF-8 encoded
For this convertion the documentation referes to SDK Librarys in others words Java Class or .Net Class type helper that in Salesforce.com not exist.
Please, I need a example to call the authentification service without sdk
Sorry for my bad English.
Visit: https://learn.microsoft.com/en-us/rest/api/storageservices/fileservices/authentication-for-the-azure-storage-services
I need a example to call the authentification service without sdk
We could generate signature string and specify Authorization header for the request of performing Azure storage services without installing SDK. Here is a simple working sample to list the containers, you could refer to my generateAuthorizationHeader function and Authentication for the Azure Storage Services to construct the signature string.
string StorageAccount = "mystorageaccount";
string StorageKey = "my storage key";
string requestMethod = "GET";
string mxdate = "";
string storageServiceVersion = "2014-02-14";
protected void btnlist_Click(object sender, EventArgs e)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(string.Format(CultureInfo.InvariantCulture,
"https://{0}.blob.core.windows.net/?comp=list",
StorageAccount
));
req.Method = requestMethod;
//specify request header
string AuthorizationHeader = generateAuthorizationHeader();
req.Headers.Add("Authorization", AuthorizationHeader);
req.Headers.Add("x-ms-date", mxdate);
req.Headers.Add("x-ms-version", storageServiceVersion);
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
var stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string content = reader.ReadToEnd();
StringReader theReader = new StringReader(content);
DataSet theDataSet = new DataSet();
theDataSet.ReadXml(theReader);
DataTable dt = theDataSet.Tables[2];
}
}
public string generateAuthorizationHeader()
{
mxdate = DateTime.UtcNow.ToString("R");
string canonicalizedHeaders = string.Format(
"x-ms-date:{0}\nx-ms-version:{1}",
mxdate,
storageServiceVersion);
string canonicalizedResource = string.Format("/{0}/\ncomp:list", StorageAccount);
string stringToSign = string.Format(
"{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}",
requestMethod,
canonicalizedHeaders,
canonicalizedResource);
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(StorageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
String authorization = String.Format("{0} {1}:{2}",
"SharedKey",
StorageAccount,
signature
);
return authorization;
}
Besides, please refer to Azure Storage Services REST API Reference to know more about programmatic access to Azure Storage Services via REST APIs.
I find a way to solve this.
You should use Shared Sing, here explain me:
Enter to Portal Azure
Open the Account Storage
In the General Information click on "Share sing access"
Enable all permissions that you need (In my case only Enable "File")
Enable all resources permission that you need (In my case onl Enable "Service, Container and Object")
Define and Start Date and End Date (This is the space of time that Shared Key will be valid)
Define protocol type (In my case use HTTPS)
Clic on "Generate SAS" button
After this process you will get a token like this:
?sv=2016-05-31&ss=f&srt=sco&sp=rwdlc&se=2017-11-28T04:29:49Z&st=2017-02-18T20:29:49Z&spr=https&sig=rt7Loxo1MHGJqp0F6ryLhYAmOdRreyiYT418ybDN2OI%3D
You have to use this Token like Autentication
Example Call Code List a Content:
public with sharing class CallAzureRestDemo {
public string token = '&sv=2016-05-31&ss=f&srt=sco&sp=rwdlc&se=2017-02-19T04:00:44Z&st=2017-02-18T20:00:44Z&spr=https&sig=GTWGQc5GOAvQ0BIMxMbwUpgag5AmUVjrfZc56nHkhjI%3D';
//public Integer batchSize;
public CallAzureRestDemo(){}
public void getlistcontent(String endpoint)
{
// Create HTTP GET request
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(endpoint+token);
Http http = new Http();
HTTPResponse res;
System.debug(LoggingLevel.INFO, '##RESPONSE: '+res);
// only do this if not running in a test method
if(!Test.isRunningTest())
{
System.debug(LoggingLevel.INFO, 'Sending the message to Azure');
res = http.send(req);
System.debug(LoggingLevel.INFO, 'http.send result status: ' + res.getStatus());
}
else
{
System.debug(LoggingLevel.INFO, 'Running in a test so not sending the message to Azure');
}
}
}
Example TestMethod:
#isTest
private class Test_CallAzureRestDemo {
static testMethod void myUnitTest() {
CallAzureRestDemo oRest = new CallAzureRestDemo();
try{
//Call the method and set endpoint
oRest.getlistcontent('https://accountstoragecomex.file.core.windows.net/?comp=list');
}catch(Exception e){
System.debug('##'+e);
}
}
}
Example to Response:
20:15:47.64 (79388244)|CALLOUT_REQUEST|[100]|System.HttpRequest[Endpoint=https://accountstoragecomex.file.core.windows.net/?comp=list&sv=2016-05-31&ss=f&srt=sco&sp=rwdlc&se=2017-02-19T04:00:44Z&st=2017-02-18T20:00:44Z&spr=https&sig=GTWGQc5GOAvQ0BIMxMbwUpgag5AmUVjrfZc56nHkhjI%3D, Method=GET]
20:15:47.64 (395755012)|CALLOUT_RESPONSE|[100]|System.HttpResponse[Status=OK, StatusCode=200]
Example Call Service "FILE - Get List Share"
Call To List Content
One more time, Sorry for my bad english.

eBay REST API Get Offers Authetication Error

I am attempting to get eBay product IDs using the GetOffers request by sending it a product SKU.
My code is below, the problem I am currently having is that when I try to test this code is returns a 401 unauthorized. It's not returning any specific error code or anything descriptive.
I know my access token is valid I can't find any good examples on how to use this request.
public string getEbayOffers(string sku)
{
HttpResponseMessage response;
string accessToken = "tokenhere";
string param = Convert.ToBase64String(Encoding.ASCII.GetBytes(accessToken));
string url = $"sell/inventory/v1/offer?sku={sku}";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.ebay.com/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", param);
response = client.GetAsync(url).Result;
}
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsStringAsync().Result;
}
return null;
}
No need to convert your token to base64. The correct format should be "Bearer YOUR_USER_TOKEN". Replace YOUR_USER_TOKEN with your own token string.
Access token should be enough for getting offers but maybe you can try to use user token if above doesn't work.

DotNetOpenAuth Get Facebook Email Address

I have the following code where its grabbing First/Last name. I realize that email is an extended permission, but what would I need to modify to request extended permissions?
How do I get the email of an authenticated Facebook user through the DotNetOpenAuth?
fbClient = new FacebookClient
{
ClientIdentifier = ConfigurationManager.AppSettings["facebookAppID"],
ClientSecret = ConfigurationManager.AppSettings["facebookAppSecret"],
};
IAuthorizationState authorization = fbClient.ProcessUserAuthorization();
if (authorization == null)
{
// Kick off authorization request
fbClient.RequestUserAuthorization();
}
else
{
var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
var graph = FacebookGraph.Deserialize(responseStream);
// unique id for facebook based on their ID
FormsAuthentication.SetAuthCookie("fb-" + graph.Id, true);
return RedirectToAction("Index", "Admin");
}
}
}
return View("LogOn");
Add the following bits:
var scope = new List<string>();
scope.Add("email");
fbClient.RequestUserAuthorization(scope);
If you are using VS2012 built in oauth providers you just need to update your oauth package. See the last post on the following link: http://forums.asp.net/t/1847724.aspx/1. The only email I can't retrieve is MS Live. Currently I use facebook, google, and yahoo.