How to get directory details programatically in Azure AD? - node.js

I have registered a new Azure AD app for login functionality in existing vuejs and nodejs projects.
And I successfully set up login and logout functionality using #azure/msal-node npm package.
Now, I want to get the directory details after the user login to store that directory details in my local DB.
I have read many documents but didn't find any working solution. So, Please help me and share good documentation links that could be helpful for me.
After login, success get this response from Azure AD: https://i.imgur.com/7fvzNiG.png
Note:- I am referring this document: https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal

• By following the given documentation link for creating a nodejs webapp using #azure-msal, you can get the details of the signed in user through the token claims details shown in the output/results page wherein you can view it through the ‘View ID token’ link. Thus, when the details are shown, you also have an option to export these details to a database configured of your choice. But for this purpose, you will have to ensure that your node js application is integrated with Azure SQL by delegating the application created in Azure AD, the required permissions for that concerned SQL database by allowing access to it and retrieve the details from it accordingly.
Thus, you can also configure the token details to be exported from the directory in MySQL DB by configuring the same in your nodejs app as described in detail in the below link. An excerpt sample from the link is given below for reference: -
In models folder, create User and Role data model as following code:
models/user.model.js
module.exports = (sequelize, Sequelize) => {
const User = sequelize.define("users", {
username: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
}
});
return User;
};
https://www.bezkoder.com/node-js-jwt-authentication-mysql/
Would also suggest you to please refer the below SO community thread for further reference: -
MSAL Integration in React + .Net App For all Microsoft Users (Without registering or Inviting the User)

Related

How can I create a tenant with social provider with firebase admin SDK?

I found in documentation that is only possible using the console. That is true? I think that should exists a way that I can do that via api, no?
Ref: https://cloud.google.com/identity-platform/docs/multi-tenancy-managing-tenants
How can I create a tenant with social provider with firebase admin SDK?. I found in documentation that is only possible using the console
The doc you refer to explains that:
Using the Admin SDK, you can
manage tenants programmatically from a secure server environment
instead of using the console. This includes the ability to create,
list, get, modify, or delete tenants
and you can find the following example for creating a tenant. Note that by "secure server environment" the doc means a server you own on which you execute Admin SDK code or a Cloud Function.
admin.auth().tenantManager().createTenant({
displayName: 'myTenant1',
emailSignInConfig: {
enabled: true,
passwordRequired: false, // Email link sign-in enabled.
},
// TODO: Remove if you don't want to enable multi-factor authentication.
multiFactorConfig: {
state: 'ENABLED',
factorIds: ['phone']
},
// TODO: Remove if you don't want to register test phone numbers for use
// with multi-factor authentication.
testPhoneNumbers: {
'+16505551234': '145678',
'+16505550000': '123456'
},
})
.then((createdTenant) => {
console.log(createdTenant.toJSON());
})
.catch((error) => {
// Handle error.
});
I know this is a bit late but it looks like adding social logins to a tenant via the admin sdk is not supported at the moment. See this doc
My best reporoduction of the table in markdown
Feature
Google Cloud Console
Admin SDK
Email
X
X
OIDC
X
X
SAML
X
X
Social
X
Phone
MFA
X
X
Anonymous
X
Your client side code is what enables the various social provider sign-in's. In other words, the admin SDK has nothing to do with it.
To setup the various social providers, see Firebase Authentication.

Pub sub with REST API - the request is missing a valid API Key

I am using the following code to do a test publish to pubsub
var data = {
file: 'ciao',
content_type: 'image/png'
};
needle
.post('https://pubsub.googleapis.com/v1/projects/topic:publish', data, {
multipart: true
},
function(err, resp) {
if (err)
console.log('Error: ' + err.message);
else
console.log('OK.' + JSON.stringify(resp.body));
});
But I get the error
{"error":{"code":403,"message":"The request is missing a valid API key.","status":"PERMISSION_DENIED"}}
Do I need a service account authorized to PubSub? Any hint on how to solve this issue?
You will need to verify the credentials you are using and the account permissions that those credentials have.
One of the popular approach is to have a service-account.json file with the credential information and use it as an enviroment variable GOOGLE_APPLICATION_CREDENTIALS. You can get that file when creating a credential account for your pub/sub application. Examples on how to create that you can find it on this link under Setting up authentication for server to server production applications..
Now you also need to verify the permissions and roles you credential account have. For cloud pub/sub there are lot of roles, like roles/editor or roles/pubsub.editor for the scope of your test run. You can even use a sample called testing_permissions from the official documentation to test your access. For a full lists of permissions and roles please see this site.
For more details you can check the access and authentication page

Google API Node.js Library - Permission denied on `getIamPolicy` for projects in organization

Goal
get and set IAM Policies for auto-provisioned GCP Projects and Service Accounts within said projects using the Node.js Client Library for Google APIs. As well as give a the service account in the project the Dialogflow API Admin role (roles/dialogflow.admin)
Issue
I get the following error when I try to get the IAM policy for a project I just automatically created.
Error: 7 PERMISSION_DENIED: Permission 'resourcemanager.projects.getIamPolicy' denied on resource '//cloudresourcemanager.googleapis.com/projects/va-31b899e6' (or it may not exist).
at Object.callErrorFromStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/client.js:180:52)
at Object.onReceiveStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:365:141)
at Object.onReceiveStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:328:181)
at /home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/call-stream.js:182:78
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
code: 7,
details: "Permission 'resourcemanager.projects.getIamPolicy' denied on resource '//cloudresourcemanager.googleapis.com/projects/va-31b899e6' (or it may not exist).",
metadata: Metadata {
internalRepr: Map(3) {
'grpc-server-stats-bin' => [Array],
'google.rpc.errorinfo-bin' => [Array],
'grpc-status-details-bin' => [Array]
},
options: {}
},
note: 'Exception occurred in retry method that was not classified as transient'
}
Here is the function I am trying to do this in.
async function setServiceAccountRolesV2(projectID, serviceAccountID){
const authClient = await auth.getClient();
const resourcemanagerClient = new ProjectsClient();
var request = {
resource: "projects/"+projectID,
auth: authClient
}
await resourcemanagerClient.getIamPolicy(request, function(err, response) {
if (err) {
console.error(err);
return;
}
console.log(JSON.stringify(response, null, 2));
});
}
Authentication Info
I am using a service account key to authenticate all of my functions in this node app with. This service account has the following permissions granted at the organization level
This service account I am using to authenticate my app with succeeds at getIamPolicy when I try to get the policy of the project it was created in itself. But I get the error when I try to get the policy of new projects I have created using this "admin project" service account.
Summary
Why is permissions denied when trying to get the IAM Policy of projects I have created programmatically, but successful when getting the policy of the "admin" project that I have this service account and the node.js app running. I thought that if I granted my service account proper permissions at the organization level, and the projects I am creating programmatically were in that same organization, my authenticating service account should inherit all of the right permissions to grant service account roles and change IAM policy in these newly generated accounts.
A potential thought/gut feeling I have that could be completely wrong - is it possible these new projects I'm making don't have IAM Policies at all? so when I try to get and set them there's nothing to change?
Update for clarifications
I have a project that acts as an "administration project" which contain hosts the VM my Node.js app for provisioning GCP resources runs on.
This project is also where I created my service account that the Node.js app authenticates with.
I am creating new projects and service accounts within those projects with this Node.js app.
I have given the aforementioned service account the Owner permission at the organization level.
In my setServiceAccountRolesV2() method, I have tried making the resource my provisioned project manually, as opposed to passed as a parameter to make sure the the project is located correctly. I manually copy and pasted the project ID from one of the auto-provisioned projects into the resource field like this for example
resource: "projects/va-31b899e6",
and I get the same permission denied error (full error message shown above).
However when I try to use this getIamPolicy method with the "admin" project that my node.js app and service account were created in, I get a successful policy return.
resource: "projects/provisioning-admin-339515"
I don't understand why one works, and one doesn't while the service account I'm using to make the call has Owner role at the organization level. The va-31b899e6 project shown above is in fact under the same organization my admin project is.
When I run the gcloud command gcloud projects get-iam-policy va-31b899e6 --format=json > ~/policy.json to check the policy of the api-generated project (not the admin project), I get the following policy back:
{
"bindings": [
{
"members": [
"serviceAccount:tf-admin-sa#provisioner-admin-339515.iam.gserviceaccount.com" ],
"role": "roles/owner"
}
],
"etag": "ByXXh29efSc=",
"version": 1
}
This service account listed in the members is the service account I authenticate my Node app with. Again, Owner granted at the Org level. This to me looks like it should be able to use the get and setIamPolicy methods on this project, as well as any other project in my organization.
New edits to follow trouble shooting tips from answer.
1
Confirmed I am using the correct project in the api call:
async function setServiceAccountRolesV2(projectID, serviceAccountID){
const authClient = await auth.getClient();
const resourcemanagerClient = new ProjectsClient();
var request = {
resource: "projects/va-31b899e6",
auth: authClient
};
await resourcemanagerClient.getIamPolicy(request, function(err, response) {
if (err) {
console.error(err);
return;
}
console.log(JSON.stringify(response, null, 2));
});
}
(project ID copied from GCP Console) : resource: "projects/va-31b899e6",
2
I have verified my credentials are used correctly, I am using a json key file of the service account I created to create more projects and service accounts programmatically. This is how I am authenticating :
const auth = new google.auth.GoogleAuth({
keyFile: 'provisioner-admin-339515-411d1e284a77.json',
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});
Then in my function, I create a new instance of auth like this:
const authClient = await auth.getClient();
which is then sent in the request of the api call: auth: authClient
3
Verified permissions for my authenticating service account:
When I run
gcloud projects get-iam-policy va-31b899e6 \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:tf-admin-sa#provisioner-admin-339515.iam.gserviceaccount.com"
I get the output ROLE: roles/owner
Your service account has too many roles. Most of the roles are redundant and included within other roles that you assigned. For example, Billing Account Administrator contains the permissions of Billing Account User. The role Owner possesses almost all of the roles in your screenshot.
Next, you need to understand the Principle of Least Privilege. Seth Vargo put together a good intro video. In summary, only grant the required privileges and no more. Your service account IAM roles are vast and a serious security weakness.
To solve the problem in your question, follow these steps:
STEP 1:
Confirm that the Project ID is correct in the API call. Make sure you are using the Project ID and not the Project Name. List the projects:
gcloud projects list
STEP 2:
Verify that your code is using the correct credentials (the ones you think you configured). Your question does not show how you are authorizing your code. You are using ADC (Application Default Credentials) which means the credentials could be found from several sources (CLI remembered credentials, the environment variable, metadata server).
If you are using the environment variable GOOGLE_APPLICATION_CREDENTIALS, open the file using the variable and make sure that it is a service account JSON key:
vi $GOOGLE_APPLICATION_CREDENTIALS
If you are using the CLI credentials, verify which identity is being used:
gcloud auth list
As a debugging test, clear the environment variable and use a user identity that has the role Owner and then login. Then retest your application.
unset GOOGLE_APPLICATION_CREDENTIALS
gcloud auth application-default login
STEP 3:
Once you have determined the correct Project ID and which service account your code is using, double-check the roles assigned to the service account at the project level. List the IAM roles with this command. Replace with your Project ID and Service Account Email address:
gcloud projects get-iam-policy <PROJECT_ID> \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:<SERVICE_ACCOUNT_EMAIL>"
The service account needs one of these roles or similar to view IAM bindings:
roles/browser aka Browser
roles/iam.roleViewer aka Viewer
The service account needs this role or similar to modify IAM bindings:
roles/resourcemanager.projectIamAdmin aka Project IAM Admin
Manage access to projects, folders, and organizations

Stripe Connect create accounts from server

I'm trying to create a stripe connect account using my firebase functions backend when the user signs up but keep getting this error Express accounts may only be created via the OAuth flow I know the error seems self-explanatory that I need to use the standard OAuth registration method but in the Documentation it states that custom types can be created by the API and presenting the OAuth for every user who just wants to send funds and not receive is just annoying am I doing something wrong for the API not to create it? Or is there a workaround to not have to show the OAuth for users who just want to send funds?
exports.createStripeCustomer = functions.auth.user().onCreate(async (user) => {
const customer = await stripe.customers.create({email: user.email});
const account = await stripe.accounts.create({type: 'custom', business_type: 'individual', individual: {email: user.email}, requested_capabilities: ['card_payments', 'transfers'], email: user.email});
return admin.firestore().collection('stripe_customers').doc(user.uid).set({account_id: account.id, customer_id: customer.id});
});
Express Accounts and Custom Accounts are distinct types of accounts when using Connect. You can create Custom Accounts using the API, but Express Accounts must be created via OAuth.
The main difference is that Express Accounts have access to the Stripe Dashboard and can be updated in some ways by the end user, while Custom Accounts are entirely managed by the platform.
The issue seems to be being caused by me not specifying the Country in the stripe.accounts.create function. Once I did it created the account.

Azure - Data only for the owner

I use an Azure Mobile Serivce to save data from my app useres in my Windows 8 Store App. I want to publish the app in the app store but for this I have to be sure every user can only get his own data. If 10 people upload data to my Azure service they should only be able to get their own data. How can I do this?
You should check the Use scripts to authorize users in Mobile Services tutorial it will show you how to partition the data per user
Basically you have to write custom scripts server side (directly in the Azure Portal in the Mobile Service script section) for the Insert operation like this
function insert(item, user, request) {
item.userId = user.userId;
request.execute();
}
And the Read operation like this
function read(query, user, request) {
query.where({ userId: user.userId });
request.execute();
}
But first you will have to add authorization to your app as shown in the Get started with authentication in Mobile Services tutorial

Resources