Directory API returns 403 forbidden - google-api

i'm trying to use the directory API by using a service account that I've enabled his Domain-wide Delegation and off course also authorized this service from the admin console using the json file credetials downloaded when creating the service account.
I've also enabled the admin sdk from the google developers console
and i'm using the googleapi library
in order to get access token for the service account
import * as google from 'googleapis';//google sdk for api+Oauth
//creating JWT auth client for service account:
const jwtClient = new google.auth.JWT(
client_email,
null,
private_key,
scope, // (included the "https://www.googleapis.com/auth/admin.directory.user" scope)
null,
);
let tokens
jwtClient.authorize( (err, tokens)=> {
if (err) {
console.log(err);
return;
} else {
tokens = tokens
}
// Make an authorized request to list of domain users.
let url = `https://www.googleapis.com/admin/directory/v1/users?domain=mydomain`;
let headers = {
"Content-Type": "application/json",
"Authorization": `Bearer ${tokens.access_token}`
}
request.get({
url: url,
json: true,
headers: headers,
}, (err, res, body: {}) => {
this.handleResponse(err, res, body, resolve, reject);
});
});
})
}
the tokens are retrived succefully but when sending the users list request i'm receiving 403 "Not Authorized to access this resource/api"
on the other hand when using the google explorer api with the same params it work's

Looks like you didn't provide a subject when constructing the JWT object (in the line after scope, in your code). You should provide the email address of an admin there, so that you get a token impersonating that admin. Otherwise, you're acting as the service account itself, that doesn't have access to your domain's directory (and can never have access - that's why you must impersonate an admin).

Related

Microsoft Graph API /me/people 403 forbidden error

I am getting 403 Forbidden error while trying to use /me/people to get a list of contacts on Outlook. This is working on Graph Explore, but not in my application.
try {
const response = await axios({
method: 'get',
url: 'https://graph.microsoft.com/v1.0/me/people',
headers: {
Authorization: `Bearer ${req.user.accessToken}`,
},
});
res.send(response.data);
} catch (err) {
console.error(err);
}
My guess is the token that you're using doesn't have enough permissions. According to the documentation for GET /v1.0/me/people at https://learn.microsoft.com/en-us/graph/api/user-list-people?view=graph-rest-1.0&tabs=http you need People.Read or People.Read.All. Can you confirm you have those in the access token?
What this means is when users login to your application with their Microsoft account they'll be prompted to give your app access to their contacts. If you're writing an app that runs without user interaction (background process) you should follow these steps for authorizing your application.

How to properly set Authorization to consume Wordpress Rest API (Oauth1) with Nativescript[2.5.4]?

I'm trying to consume the WP Rest API with Nativescript.
The WP API and the Authorization with OAUTH1 is already well setup and tested with POSTMAN.
Nativescript Login function to consume rest is already setup too and work without OAUTH.
Now I'm trying to Login with OAUTH here the code :
authorizationString = 'OAuth oauth_consumer_key="T2yXcbN28Ufj",
oauth_token="AmEVr5oSNmbKyZKccFjtmnSk",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1492267438",
oauth_nonce="rGFJG2",
oauth_version="1.0",
oauth_signature="Ru%2BaSvsZn2liesd2ENy8GeNsdHY%3D"';
login(user: User){
console.log("Try to login User : " + user.email);
let headers = new Headers({"Authorization": authorizationString});
let body = JSON.stringify({
username: user.username,
email: user.email,
password: user.password
});
headers.append("Content-Type", this.contentType);
return this.http.post(
this.api,
body,
{headers: headers}
)
.map( response => response.json() )
.do(data => {
//Do work!!
})
.catch(this.handleErrors);
}
But i got an error, this error means the autorization is not well formatted or sent :
"data": {
"code": "rest_cannot_access",
"message": "Only authenticated users can access the REST API.",
"data": {
"status": 401
}
}
How to properly use oauth1 with Nativescript?
I just switched to OAUTH2 by using a opensource plugin :
https://github.com/wlcdesigns/WP-OAuth2-Server-Client
and it's more easy to use with the authorization : Bearer

google ExchangeCodeForTokenAsync invalid_grant in webapi

i have implemented GoogleAuthorizationCodeFlow scenario from google api client dotnet and tutorial to get token from what my client sent to server as a code. but when i call flow.ExchangeCodeForTokenAsync , I get the following error :
{"Error:\"invalid_grant\", Description:\"\", Uri:\"\""}
I read google authorization invalid_grant and gusclass oauth 2 using google dotnet api client libraries but they didn't help me and. I think it must be very simple but I don't know why it doesn't work.
For client side , I have used Satellizer and this is my server Codes:
public bool PostExchangeAccessToken(GoogleClientAccessCode code)
{
string[] SCOPES = { "email" };
IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets()
{
ClientSecret = "******",
ClientId = "********.apps.googleusercontent.com"
},
Scopes = SCOPES
});
try
{
TokenResponse token;
token = flow.ExchangeCodeForTokenAsync("*****#gmail.com", Newtonsoft.Json.JsonConvert.SerializeObject(code), "https://localhost:44301/",
CancellationToken.None).Result;
}
catch (Exception ex)
{
throw ex;
}
return true;
}
what is the problem?
On Github I found that I must use the Token from the client and use
GoogleAuthorizationCodeFlow.Initializer()
to create my UserCredential object.
You can check your google developer console settings.(Authorized redirect URIs)
Credentials => OAuth 2.0 client IDs => Your Application Settings => Authorized redirect URIs
You must add url. ("https://localhost:44301/")
My code :
flow.ExchangeCodeForTokenAsync("me", authCode, redirectUri, CancellationToken.None).Result;
Authorized redirect URIs
For use with requests from a web server. This is the path in your application that users are redirected to after they have authenticated with Google. The path will be appended with the authorization code for access. Must have a protocol. Cannot contain URL fragments or relative paths. Cannot be a public IP address.

Okta Authentication works but Get User by Id gives Invalid Token Provided

I have a Django app that authenticates using Okta:
headers = {
'Authorization': 'SSWS {}'.format(<okta api token>),
'Accept': 'application/json',
'Content-Type': 'application/json'
}
authentication_payload = {
'username': <username>,
'password': <password>
}
response = requests.post(
<okta auth endpoint>,
headers=headers,
data=json.dumps(authentication_payload)
)
This works successfully. From the response content I am able to get the User Id:
content = json.loads(r.content.decode('utf-8'))
okta_user_id = content['_embedded']['user']['id']
I then use the okta_user_id to create the endpoint to get the okta user by id:
okta_user_endpoint = https://<org>.okta.com/api/v1/users/<okta_user_id>
I then use the same headers from the authentication call, with the same api token, and try to get the user by id:
user_response = requests.get(
okta_user_endpoint,
headers=headers
)
But this is unsuccessful. I get a 401 error with the following content:
{
"errorCode":"E0000011",
"errorSummary":"Invalid token provided",
"errorLink":"E0000011",
"errorCauses":[]
}
Seems straight forward with an invalid token, but if the token is invalid how am I able to successfully make the authentication call? And if the token if valid for the authentication call why is it not working to get the user by id?
Okta recently changed the way that the /authn endpoint works. The /authn endpoint no longer requires an authentication token. This was done in order to support single-page applications.
It looks like your application will need to be able to fetch user information on an arbitrary user. In that case, using an Okta API token makes sense.
However, if you were making that call from a single-page application, you would want to make a request to the /users/me API endpoint.

Request with token from ADAL for Cordova returns 401 response from Web Api

I'm hoping someone can help with this:
I have a web api secured with Azure AD Bearer Authentication, where I have two web clients that can successfully authenticate on the web api using bearer tokens from AD. The Web API and both web applications are configured as applications in AD. I've tried to use ADAL for Cordova for accessing the web api a iOS/Android app but it's returning 401.
ClaimsPrincipal.Current.Identity.IsAuthenticated is returning false.
I'm using the client id for the native application I've setup in Azure AD, and I'm receiving the token but this token is invalid. After I've parsed the token on jwt.io, everything seems correct but I've noticed the token doesn't have a header.
I've added permissions to access the Web Api and sign in and access AD as the user.
The code I'm using in Cordova is below, the authority I'm using is the same as the other apps that are working. Where resource is the app Id for the Web Api in AD, and client id is the client id for the native app in Azure Ad.
// Attempt to authorize user silently
AuthenticationContext.acquireTokenSilentAsync(resource, clientId)
.then(function (result) {
sessionService.logIn(result.idToken);
console.log(result);
deferred.resolve();
}, function () {
// We require user credentials so triggers authentication dialog
AuthenticationContext.acquireTokenAsync(resource, clientId, redirectUri)
.then(function (result) {
console.log(result);
sessionService.logIn(result.idToken);
deferred.resolve();
}, function (err) {
console.log("Failed to authenticate" + err);
deferred.reject("failed to authenticate");
});
});
I've also tried using result.accessCode, which also doesn't work.
StartUp.Auth.cs in Web Api:-
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters {
ValidAudiences = Audiences
}
});
}
Can anyone help please?
Thanks
You appear to be sending the wrong token to the API - you are supposed to send result.accessToken. See https://github.com/Azure-Samples/active-directory-cordova-multitarget/blob/master/DirSearchClient/js/index.js for an example.

Resources