I was creating the sample to get all the google calendar events and show the events with details on list. But it always throws the exception while fetching the data.
I tried to get events by follow the below link
https://www.c-sharpcorner.com/article/get-and-create-google-calendar-events-from-net/
and i also refer the google link also
https://developers.google.com/api-client-library/dotnet/get_started#simple
The issue was raised on make a request and i tried with both API key and client service.
I created the calendar credential by
GoogleCredential credential;
using(var stream = new FileStream(keyfilepath, FileMode.Open, FileAccess.Read)) {
credential = GoogleCredential.FromStream(stream)
.CreateScoped(Scopes).CreateWithUser("demo123#gmail.com");
}
var service = new CalendarService(new BaseClientService.Initializer() {
HttpClientInitializer = credential,
ApplicationName = "Calendar Sample",
});
EventsResource.ListRequest request = service.Events.List("primary");
Events events = request.Execute(); /// Makes crash
Android Crash : System.Net.WebException: 'Unable to resolve host "oauth2.googleapis.com": No address associated with hostname'
Windows : Google.Apis.Auth.OAuth2.Responses.TokenResponseException: 'Error:"unauthorized_client", Description:"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.", Uri:""'
Suggest me to resolve the problem.
Related
We are generating agora token from token server provided by agora but the token expires immmediately after the generation it throws DYNAMIC-KEY-EXPIRY with error code 109 and i have tried using onRequestToken() call back method provided in SDK below is the code snippet
override fun onRequestToken() {
//this will be called when the token expires
//so generate new token and renew the existing token
runOnUiThread {
regenerateToken()
}
}
and getting another token from server and renewing the token using mRtcEngine.renewToken(token)
we have contacted agora team regarding this but unable to find the issue the token generated works sometimes,we have two account one is test account and other is main account when we use the one credentials it works for a day or so and after we need to change the credentials for every 2 days
and the new generated token is expiring just after the generation
So if any one faced the same issue and any help regarding this is appreciated
When you generate the token, you can set the token expiration time in the request parameter. Here is a guide for token generation. https://docs.agora.io/en/Video/token_server?platform=Android
If you have set the expiration time but still having the issue, please let me know.
We are generating the token using agora token server and the time expiration is 3600
const { RtcTokenBuilder, RtmTokenBuilder, RtcRole, RtmRole } = require('agora-access-token');
const role = RtcRole.PUBLISHER;
const expirationTimeInSeconds = 3600
const currentTimestamp = Math.floor(Date.now() / 1000)
const privilegeExpiredTs = currentTimestamp + expirationTimeInSeconds
const generateAuthTokenToInititateCall = async (channel, cb) => {
const token = RtcTokenBuilder.buildTokenWithUid(appID, appCertificate, channel, 0, role, privilegeExpiredTs);
cb({ "token": token, "channel": channel })
}
this is the node js code snippet
Is anyone able to resolve this? This is occurring despite setting the expiration to 3600 seconds (1 hour from current time).
let me make this token generation for you very simple and also the later process.
*firstly how to generate token?
you need a backend server which provides you with token when you provide the server a channel name. no where you will be told that this backend server is not necessary. rather you can copy - paste the token generation code directly into the app in a form of directory.
*where is this token generation code?
https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey/java/src
this code is available for flutter also research a little bit.
*how to generate token using it?
once you have the all java files in your project you can use them to generate the token. here you can see a variable expirationTimeInSeconds, that will be the total time you want token to be active. rest all work leave it to the code it will do it for you.
package io.agora.sample;
import io.agora.media.RtcTokenBuilder;
import io.agora.media.RtcTokenBuilder.Role;
public class RtcTokenBuilderSample {
static String appId = "970CA35de60c44645bbae8a215061b33";
static String appCertificate = "5CFd2fd1755d40ecb72977518be15d3b";
static String channelName = "7d72365eb983485397e3e3f9d460bdda";
static String userAccount = "2082341273";
static int uid = 2082341273;
static int expirationTimeInSeconds = 3600;
public static void main(String[] args) throws Exception {
RtcTokenBuilder token = new RtcTokenBuilder();
int timestamp = (int)(System.currentTimeMillis() / 1000 + expirationTimeInSeconds);
String result = token.buildTokenWithUserAccount(appId, appCertificate,
channelName, userAccount, Role.Role_Publisher, timestamp);
System.out.println(result);
result = token.buildTokenWithUid(appId, appCertificate,
channelName, uid, Role.Role_Publisher, timestamp);
System.out.println(result);
}
}
result here is the generated token which is valid for 3600 seconds, that is 1hour.
I'm having trouble to properly use the integration of user pools with the API gateway from my Android app. (As per this documentation http://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html)
The API Config
Authorizer for my user pool configured and the method configured to use the authorizer. Body mapping template:
#set($inputRoot = $input.path('$'))
{
"userid" : "$context.authorizer.claims.sub"
}
The Android App
The following is only a collection of copy and paste snippets since it's scattered across different place in the app.
// init
credentialsProvider = new CognitoCachingCredentialsProvider(
context,
IDENTITY_POOL_ID,
IDENTITY_POOL_REGION);
userPool = new CognitoUserPool(
context,
USER_POOL_ID,
CLIENT_ID,
CLIENT_SECRET,
new ClientConfiguration(),
USER_POOL_REGION);
// login
user = aws.userPool.getUser(username);
user.getSessionInBackground(authHandler);
String token = session.getIdToken().getJWTToken();
Map<String, String> logins = new HashMap<>();
logins.put(USER_POOL_ARN, token);
aws.credentialsProvider.setLogins(logins);
aws.credentialsProvider.refresh();
// using the api
ApiClientFactory factory = new ApiClientFactory().credentialsProvider(
aws.credentialsProvider);
apiClient = factory.build(MyAPIClient.class);
apiClient.mainGet()
The current result
com.amazonaws.mobileconnectors.apigateway.ApiClientException: {"message":"Unauthorized"}
(Service: MyAPIClient; Status Code: 401; Error Code: null; Request ID: cefd713c-1234-1234-1234-b9e32fbdedb0)
at com.amazonaws.mobileconnectors.apigateway.ApiClientHandler.handleResponse(ApiClientHandler.java:294)
at com.amazonaws.mobileconnectors.apigateway.ApiClientHandler.invoke(ApiClientHandler.java:111)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy2.mainGet(Unknown Source)
at com.my.mainGet(my.java:206)
So I can imagine that initializing the credentials provider with an identity pool will lead to a an identity token but I really need a token from the user pool. However that leads me to the question of how do I setup my ApiClient properly to use the user pool token?
I've got InvalidAccessTokenException at any attempt to upload file to Dropbox.
For authorization I use next algorithm:
Auth.startOAuth2Authentication(context, APP_KEY);
//granting access
//previous activity is reopened
String accessToken = Auth.getOAuth2Token();
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder(CLIENT_ID)
.withHttpRequestor(OkHttp3Requestor.INSTANCE)
.build();
DbxClientV2 client = new DbxClientV2(requestConfig, accessToken);
client.files().uploadBuilder(ADDRESS_IN_DROPBOX)
.uploadAndFinish(inputStream);
which returns InvalidAccessTokenException.
Maybe I'm doing something wrong.
Also maybe Auth.getOAuth2Token() return auth code instead of access code (which is a bit obvious from method name), but how to get access code when auth code is known?
PS I've used Android project as example - https://github.com/dropbox/dropbox-sdk-java/tree/master/examples/android and performed auth exactly as in example.
EDIT-----------------------------------------------------------------------------------------------
Problem occurs ONLY after revoking access to the app from account settings at Dropbox webpage.
You noted:
Problem occurs ONLY after revoking access to the app from account settings at Dropbox webpage.
In that case, this InvalidAccessTokenException is expected. If a user revokes the token, e.g., by unlinking the app via https://www.dropbox.com/account/security , any further API calls attempted with that token will fail with this exception. You should have your code catch this exception and prompt the user to re-link the app if they want to continue using it.
I found problem in my code.
I've used DropboxClientFactory like in example from Dropbox where client init looks like this
public static void init(String accessToken) {
if (sDbxClient == null)) {
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder("ID")
.withHttpRequestor(OkHttp3Requestor.INSTANCE)
.build();
sDbxClient = new DbxClientV2(requestConfig, accessToken);
}
}
And when access token was revoked - init process was not called because sDbxClient is already initialized.
So I added variable accessCode to DropboxClientFactory to hold used access token and now init looks like this
public static void init(String accessToken) {
if (sDbxClient == null || !accessToken.equals(accessCode)) {
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder("ID")
.withHttpRequestor(OkHttp3Requestor.INSTANCE)
.build();
sDbxClient = new DbxClientV2(requestConfig, accessToken);
}
}
Intermittently, GoogleTokenResponse.parseIdToken() has an NullPointerExpection because the token response does not contain an ID token. Without changing any code, sometimes there is an ID token, and sometimes there isn't. Note that GoogleTokenResponse.getAccessToken() always works.
With no change to any code whatsoever, the ID token will be missing from one minute to the next, even if the access token is always available.
How can I debug this? Where to look?
I get the server auth code using this in an Android client using Google Play Games API:
PendingResult<Games.GetServerAuthCodeResult> pendingResult =
Games.getGamesServerAuthCode(mGoogleApiClient, Constants.web_client_ID);
pendingResult.setResultCallback(new ResultCallback<Games.GetServerAuthCodeResult>() {
#Override
public void onResult(Games.GetServerAuthCodeResult getTokenResult) {
sendToServer(getTokenResult.getCode());
}
});
On the server side (Google Cloud Endpoints), I exchange the code for a token using this code:
try {
tokenResponse = new GoogleAuthorizationCodeTokenRequest(
transport,mJFactory,
"https://www.googleapis.com/oauth2/v4/token",
web_client_ID,web_client_secret,
authCode,
"")
.execute();
} ...
String accessToken = tokenResponse.getAccessToken();
GoogleIdToken idToken = null;
try {
idToken = tokenResponse.parseIdToken(); //-- FAILES HERE INTERMITTENTLY!!!!
} ...
Since it seems that Play Games Services does not guarantee an ID token using Games.getGamesServerAuthCode one should follow the directions in this post and get the ID token as it recommends:
Once you have the access token, you can now call
www.googleapis.com/games/v1/applications//verify/ using that
access token. Pass the auth token in a header as follows:
“Authorization: OAuth ” The response value will contain
the player ID for the user.
See this for a full example.
I'm trying to access a Purchase Status API from my ASP.NET web server using Google APIs .NET Client Library which is a recommended way for using Purchase API v1.1. However, the Authorization page of this API suggests direct web requests to Google's OAuth2 pages instead of using the corresponding client libraries.
OK, I tried both methods with all variations I could imagine and both of them lead to "The remote server returned an error: (400) Bad Request.".
Now what I've done to get to my point. First I've made all steps 1-8 under the Creating an APIs Console project of the Authorization page. Next I generated a refresh token as described there. During refresh token generation I chose the same Google account as I used to publish my Android application (which is in published beta state now).
Next I've created a console C# application for test purposes in Visual Studio (may be console app is the problem?)
and tried to call the Purchase API using this code (found in some Google API examples):
private static void Main(string[] args)
{
var provider =
new WebServerClient(GoogleAuthenticationServer.Description)
{
ClientIdentifier = "91....751.apps.googleusercontent.com",
ClientSecret = "wRT0Kf_b....ow"
};
var auth = new OAuth2Authenticator<WebServerClient>(
provider, GetAuthorization);
var service = new AndroidPublisherService(
new BaseClientService.Initializer()
{
Authenticator = auth,
ApplicationName = APP_NAME
});
var request = service.Inapppurchases.Get(
PACKAGE_NAME, PRODUCT_ID, PURCHASE_TOKEN);
var purchaseState = request.Execute();
Console.WriteLine(JsonConvert.SerializeObject(purchaseState));
}
private static IAuthorizationState GetAuthorization(WebServerClient client)
{
IAuthorizationState state =
new AuthorizationState(
new[] {"https://www.googleapis.com/auth/androidpublisher"})
{
RefreshToken = "4/lWX1B3nU0_Ya....gAI"
};
// below is my redirect URI which I used to get a refresh token
// I tried with and without this statement
state.Callback = new Uri("https://XXXXX.com/oauth2callback/");
client.RefreshToken(state); // <-- Here we have (400) Bad request
return state;
}
Then I tried this code to get the access token (I found it here: Google Calendar API - Bad Request (400) Trying To Swap Code For Access Token):
public static string GetAccessToken()
{
var request = WebRequest.Create(
"https://accounts.google.com/o/oauth2/token");
request.Method = "POST";
var postData =
string.Format(
#"code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code",
// refresh token I got from browser
// also tried with Url encoded value
// 4%2FlWX1B3nU0_Yax....gAI
"4/lWX1B3nU0_Yax....gAI",
// ClientID from Google APIs Console
"919....1.apps.googleusercontent.com",
// Client secret from Google APIs Console
"wRT0Kf_bE....w",
// redirect URI from Google APIs Console
// also tried Url encoded value
// https%3A%2F%2FXXXXX.com%2Foauth2callback%2F
"https://XXXXX.com/oauth2callback/");
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
using (var dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
}
try
{
// request.GetResponse() --> (400) Bad request again!
using (var response = request.GetResponse())
{
using (var dataStream = response.GetResponseStream())
{
using (var reader = new StreamReader(dataStream))
{
var responseFromServer = reader.ReadToEnd();
var jsonResponse = JsonConvert.DeserializeObject<OAuth2Response>(responseFromServer);
return jsonResponse.access_token;
}
}
}
}
catch (Exception ex) { var x = ex; }
return null;
}
So, to sum up all my long story:
Is it possible at all to pass OAuth2 authorization using either of methods above from a C# Console Application (without user interaction)?
I've double checked the redirect URI (since I saw a lot of discussed troubles because of it here on stackoverflow) and other parameters like ClientID and ClientSecret. What else I could do wrong in the code above?
Do I need to URL encode a slash in the refresh token (I saw that the first method using client library does it)?
What is the recommended way of achieving my final goal (Purchase API access from ASP.NET web server)?
I'll try to answer your last question. If you access your own data account, you dont need to use client id in oAuth2. Let's use service account to access Google Play API.
Create a service account in Google Developer Console > Your project > APIs and auth > Credentials > Create a new key. You will download a p12 key.
Create a C# project. You can choose console application.
Install google play api library from Google.Apis.androidpublisher. Nuget. You can find other library for dotnet in Google APIs Client Library for .NET
Link google api project with your google play account in API access
Authenticate and try to query information. I'll try with listing all inapp item. You can just change to get purchase's status
String serviceAccountEmail = "your-mail-in-developer-console#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"physical-path-to-your-key\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { "https://www.googleapis.com/auth/androidpublisher" }
}.FromCertificate(certificate));
var service = new AndroidPublisherService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GooglePlay API Sample",
});
// try catch this function because if you input wrong params ( wrong token) google will return error.
var request = service.Inappproducts.List("your-package-name");
var purchaseState = request.Execute();
// var request = service.Purchases.Products.Get(
//"your-package-name", "your-inapp-item-id", "purchase-token"); get purchase'status
Console.WriteLine(JsonConvert.SerializeObject(purchaseState));
You should do the following in your
private static IAuthorizationState GetAuthorization(WebServerClient client) method:
private IAuthorizationState GetAuthorization(WebServerClient client)
{
IAuthorizationState state = AuthState;
if (state != null)
{
return state;
}
state = new AuthorizationState()
{
RefreshToken = "4/lWX1B3nU0_Ya....gAI",
Callback = new Uri(#"https://XXXXX.com/oauth2callback/")
};
client.RefreshToken(state);
// Store and return the credentials.
HttpContext.Current.Session["AUTH_STATE"] = _state = state;
return state;
}
Let me know if it works for you.
Be aware that we know that the whole OAuth2 flow is awkward today, and we are working to improve it.