Synchronize AD user groups with backend service - azure

I am not sure if the question is descriptive enough for what i am trying to accomplish so let me try to elaborate. Because even i am not sure how to properly set the question. So i will tell more about the big picture of what i am trying to do.
I am building an application that uses AWS Cognito for user authentication and authorization. But authorization part is in a way not directly done via Cognito (more about it a bit later)
In Cognito i added as a third part identity provider Azure AD via OIDC. I also have backend service that will hold user's roles in its own database. Now, for users that are going to be added to user pool via AD i need to replicate their groups in AD as a role in my service database. (So if i have a user in AD that is part of the group ADMIN I need to get that group and put it in my own db as a role for that specific user).
Now the idea is to use MS Graph for syncing groups with roles in my service. But the point is that then i would need credentials of the AD user that has the rights to see that info in AD. Which is not really what i am trying to accomplish.
My guess is that this can be done in all at once scenario (which would require the "GODs" user in AD credentials, which is not an option), or one by one (as they login to Cognito via AD as Idp).
So to sum it up, my question is can i integrate the call to MS Graph when user logs in with its ad (microsoft) credentials, that in a way i get the info about his group when he tries to log in to Cognito userpool?
I understand that this probably is very unclear, but i am not quite sure how to put it in a simple way.
If anyone can help me out, i would appreciate it.
Thanks

You don't need to integrate the call to MS Graph.
Just include Groups claim in your token as instructed here. You just need to modify the "groupMembershipClaims" field in application manifest:
"groupMembershipClaims": "SecurityGroup"
Then the token will contain the Ids of the groups that the use belongs to like below :
{
"groups": ["{group id}"]
}

Related

What is the best way to obtain a Microsoft Graph API token through an Azure B2C logged in user so to act upon the users context

From the documentation it seems that using an application that is in the B2C tenant and thus hosts user accounts that there is no way to directly access Microsoft Graph API via a logged in user per their own context.
I want to establish the use case properly so that the solution is that which makes the most sense.
The use case is that if a user wants to edit claims for example such as permissions they would be able to do so while logged in through Azure B2C.
The flow would be. Logged in user -> can change certain claims information such as address, surname, and other custom policy fields (SEO contact permissions.)
Is the proper way to do this is to build a proxy that will take the application's AD application permissions which are allowed to call out to Microsoft Graph and pass along user context so that the scope will be limited to that user only?
For example. User logs into the app.
The app has AD permissions that are granted admin consent
Create a client secret to prove application identity upon request of a token
Now can access Microsoft Graph api
Ref of Registering an app with Microsoft Graph api
What's not clear here exactly is the next part. My user is logged in with Azure B2C. Should I just pass along their id token which has their claims to the application? How do I put in scope/context of the logged in user of the app permissioned access to Microsoft Graph?
This part is not clear in any documentation.
I don't want a logged in user to have access to everything.
Is a proxy the only way to do this?
If a proxy is the only way to do this what identifier or id is what should be used to pass along to the query to assure only that user is in context?
Am I thinking of this incorrectly and or is there a better way to do this other than a proxy?
The documentation says this.
Apps that have a signed-in user but also call Microsoft Graph with their own identity. For example, to use functionality that requires more elevated privileges than the user has.
That doesn't fit exactly into my use case above or address it really but I think it is related. The functionality should be considered to be an elevated permission but to the scope of the user. This user can change this claim via their own logged in entity. What do you call that and what is the best way to solution this?
Lastly, is there anything that should be known in the MSAL library including Angular and React that would be useful in this process? It seems like I will have to converge the 2 to obtain the access token of the app and of the person and proxy those out to a backend service (the proxy) to then do a body of work.
Am I thinking of this correctly?
This Stack is the closest to relevance but doesn't ask or solution the entire use case as I have here. But is useful for illustrating the confusion.
"Logged in user -> can change certain claims information such as address, surname, and other custom policy fields (SEO contact permissions.)"
Why can't you use the Profile Edit user flow? You can configure what attributes the user can change.

Best way to authorize with AzureAD app registration: roles or group claims when only one AD group is required for access

I have an AzureAD application registration for my front end SPA. I am using Angular with Microsoft’s #azure/msal-angular v2 authentication library. My app registration has all the necessary redirect URIs and configured for proper OAuth2 OpenID Connect using authorization code flow with PKCE. My app is using the Microsoft Graph API with only the User.Read scope. I can authenticate just fine. If my app, however, is only available for one group of people, defined by an AD group and assigned to the Users and Groups section in Azure, what is the best way to validate the logged in user is authorized? I’ve tried enabling optional group claims for the access token, but those don’t come through for some reason. I then tried adding roles-I have an “admin” role, which is the only one I need. This role is assigned to the AD group I mentioned earlier. The roles claim does come back, and I can use that, but this seems silly when I should be able to just validate if the logged in user is in my AD group. The roles approach does have the nice feature of just assigning users different roles to validate authorization for development purposes, but not sure if there’s a better way.
At some point there will be an API I need to plug in. Would it be best to get the claims from that and use that for validation?
Is there a scope or setting I’m missing? Am I achieving this all wrong? Thank you to all who reply.
At this point, you have a SPA that calls a MS 1st party API, which is MS Graph.
Since you are acquiring an accessToken to MS Graph, this accessToken can not be changed - it is meant to be decoded and validated by MS Graph itself, so you will not be able to add any extra claim on that token since you do not control the resource.
Also, your client should treat the accessToken as an opaque string, you should never rely on any claim from the accessToken on the frontend.
You can read more about it here:
https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens
If you want to do some sort of authorization on the frontend, like deciding which routes your user will have access to, you need to rely on the idToken. For the idToken, you can enable the Groups claim and get a list of groups that the user is a member of.
If, as mentioned, later down the line you need to create a custom API and call it from your SPA, then, on that scenario, you can indeed add the Groups claim to the accessToken, because it will be a resource that you control, and then authorize the requests that hit your API based on that claim
MS has a sample that shows exactly how to use security groups for access control, using an Angular frontend with a .NET Core Web API. Give it a check here:
https://github.com/Azure-Samples/ms-identity-javascript-angular-tutorial/blob/main/5-AccessControl/2-call-api-groups/README.md

Azure B2C integration with sql server authorization scheme and unique validation - do I use Identity Experience Framework?

I need help determining how to integrate the Azure B2C authentication with the authorization within my app. I got the susi (sign up sign in) user flow working, but I need to do two things. First, I need to validate the alias to ensure no other such alias already exists and I need to add the user to my sql server database to ensure they are available for authorization processes (eg: users can allow other users to view/edit their resources).
I saw this video, which seems to cover what I want to do, but I think I could use some explanation. This article also seems to come close, but it is returning keys from a database as opposed to inserting into a database. That seems like minor change.
It seems like I need to replace the susi user flow with a B2C Identity Experience Framework policy, but I still want the other steps to be completed. I think I should download the susi policy and edit it and upload it to the IEF, but I am not sure.
I previously was trying to capture the events in a web app in the Startup.cs file when configuring the service during the OnTicketReceived event, like this, but this didn't cover mobile apps, so I think the IEF solves for this by including the steps in the flow.
I just want to confirm this is the right way to accomplish what I am looking to accomplish and seeing if anybody has any step by step examples.
It seems like it would be a good tutorial to show starting with a working susi user flow and editing it to add integration with an Azure Function.
Using IEF by calling the REST API will be the right way to accomplish your requirement. During the signup process, execute a restful technical profile which will call an REST API service there you can validate the user existance in your local DB and create the user in the database and proceed the registration process in B2C tenant.
Another approach would be after signing up the user can be created by the service and for the first call, service can insert a claim for itself with new database user Id.
There is a sample showing how to implement RBAC in B2C using security groups. If the role model is very simple, you could also consider attaching them directly to the user object as custom claim.

How to control/set permissions for a single user when using Azure AD B2C

I have 1 SPA-Application which uses another WebApi. (ASP.NET Core) Both are running in Azure and I am able to authenticate the user against Azure AD B2C with OAuth 2.0 Implicit Flow
Now I am asking myself how I can control the permissions of a single user. (Delete, Read, etc.) Do I have to work with claims? Do I have to leverage the graph API on the server side to check if a user has a certain permission? Can I use scopes? Where can I set the User <--> Scope relationship?
I have found several questions on SO, but I don't get the idea of how it should be done the right way? My current understanding is that I ask the authentication provider for certain scopes and I will get a token with this scopes which then can be checked by the API. But how do I manage which user can ask for which scopes?
I really have a problem to wrap my head around OAuth2 and permissions. Hope one can help me here.
Unfortunately, for one specific user, you cannot assign permissions/scopes to the user.
Because Azure AD B2C doesn't support Application Role. Generally, Azure AD B2C is for all users to access your App wit their account. Even Azure AD B2C can let you store and manage users, but it cannot assign different scopes/permissions to different users. Multiple scopes are the permissions granted to the resource. Multiple granted permissions will be separated by space.It's not for users access assignment.
If this important to you, you can upvote this idea in this Uservoice Page. Azure Team will review it.
Hope this helps!
You can implement this by creating a custom attribute of type String that stores a comma- or space-separated list of roles for a user.
You can then issue this custom attribute in the ID and access tokens or read it using the Azure AD Graph API.

Requesting Azure AD permissions on-demand

We have a multi-tenant single page app (and backend) that uses Azure AD for authenticating users. We'd like do queries to customer's Azure AD for retrieving groups but make it an opt-in behavior for customers (tenants). The reasoning behind that is that not all customers necessary need the functionality and would rather not grant us access to their AAD unnecessarily.
Is there some way of implementing this with Azure AD?
I've been trying to test with different OAuth /authorize calls with resource IDs and scopes but mostly I end up with "AADSTS65001: The user or administrator has not consented to use the application with ID ''. Send an interactive authorization request for this user and resource." error. Configuring the web app or backend to require the permission would surely fix the error but that will also make the approval of it mandatory for all users of the app.
Is there a way of using the authorize/consent API to request access to a new application on-demand?
An ugly work-around that should work would be to have 2 client IDs and 2 backend IDs with different permissions but ADAL.js doesn't seem to be designed to work with multiple Client IDs (it's singleton, for starters). Also Application Permissions should of course work but I'm not sure how much of those are required to search for groups.
Is there a way of using the authorize/consent API to request access to
a new application on-demand?
Do take a look at Azure AD v2.0. With their incremental & dynamic consent model, it is possible to do so though I am not sure if this specific functionality (managing groups) is available there.
I had a discussion with Azure AD team member recently about this (as we are also facing the same problem) and he suggested that we take a look at this.
Essentially the way things work in Azure AD v2.0 is that you start with basic set of permissions (like sign in, read profile etc.). Then when some tenant need specific permission, you essentially ask them to grant those permissions to your application at that time only. What this means is that different users in your application have granted different permissions to your application.
If you are using MSAL, and looking for a way to dynamically change your scopes before authenticating, have a look at this: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/configuration.md#msalguard---dynamic-auth-request
More here: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/configuration.md#platformbrowserdynamic

Resources