Active directory access behalf of trusted entity - oauth-2.0

I am really new to Active directory and identity management. We have different authentication strategies for an employee(Windows AD) and customer(Ping AD) handled by separate active directories. Now we have scenario where authenticated employee can process requests behalf of customer and should able to update customer profile in customer AD. I am looking for way that customer AD should trust any authenticated employee from Emp AD and grant him write permission for requested customer.
Is there any standard practice/way to achieve this ?

Related

Multi-organization solution with identityserver4

I've got following setup:
IdentityServer4 using asp.net core identity
Accounts app - where user can edit his account data and users can register
Portal - where users can login and select an organization to which they're connected (same as in azure devops)
API that is used by portal
Does anyone have experience setting up something similar ? My question would be how to authorize the calls at API level to make sure he is only editing entities that belong to his organization.
Thanks !
One way could be to use a tenant claim within each bearer token, so that when a user changes an organization on the portal (in case one user has access to several orgs), you perform relogin to the chosen tenant, or just request a new access token with a chosen tenant_id inside.
You can use this and this answers for the reference on how to pass a custom parameter (such as tenant id) with your request to Identityserver.

oAuth with Microsoft Azure AD with azure GUEST accounts vs employee accounts

I am setting up OIDC within an ASP.NET Core 3.1 web mvc application. I have setup "OpenIdConnect" for our employees specifying the authority via
"Authority": "https://login.microsoftonline.com/{0}/v2.0"
Where {0} is the companyname.onmicrosoft.com (or companyname is the tenantId) -> this works fine/well.
We have Azure GUEST accounts within our AD/ADFS and this above authority is not working for these accounts. i.e. my bob#gmail account is setup as a guest account in Azure AD. I have read that it should against companyname.onmicrosoft.com however the only way I could log in with guest access was to use authority
"Authority": "https://login.microsoftonline.com/common/v2.0"
Using common within the authority url I could log into my application. This also means I had to know what type of auth employee or guest account before user could log in (i.e. different buttons making the user choose between type of auth to perform)...this is less than ideal.
I would like to use the same Authority for both employees and guest users..is this possible?
If I use "Authority": "https://login.microsoftonline.com/{0}/v2.0" > where {0} is tenant mycompany.onmicrosoft.com and try to log in with my bob#gmail AD GUEST Account it fails and I get this error... (interesting how the redirect_uri is using common even though bob#gmail is AD guest account
This login.live.com page can’t be foundNo webpage was found for the web address: https://login.live.com/oauth20_authorize.srf?response_type=code&client_id=51483342-085c-4d86-bf88-cf50c7252078&scope=openid+profile+email+offline_access&response_mode=form_post&redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fcommon%2ffederation%2foauth2&state=rQIIAY2VOc_sZgGFv7lLkntJxAWlSHmlpCGS7_Vuv59EMbbHnvE6M17GdjN43_dlxhY_ACEK6jRIlClpQKmoU0Wiyy-IqCIqRAF8_AOaUz3FOdKRni-fo-_gxy9iAqeCKCIgDAAPwkmAQT7uYxAdUzgaEiEWR6D_-es3aPDJl78CH6vfvPnZy__87vUvvtq8upbZHL0LmurrzefpOLbD4_v3ZRN4ZdoM4yMBw8j7IUvqrIaSKRrGv2w23202P2w2Xz8bSIzCaEACEgcUQZI4TrxzqxOmCnymGqdRNQ6YusCwIqipbCSIkpujurqZxhV3xVALJT8RDrq7P_GFc1FGV9hhyhPvGg4sG2mpXszRMZy7mzuLmluFwiW375_9VNtOY4r-L5o-W6N_PHsVN311bZ_qfvX8x5-wMSfS6p5czlFoEqJW66unxfKdZabVC-FKaAKlnrdr4uTdyq4SPw8QAwKtS0uGuynwMRmBZanH3DQbUJwVp1nHpTRbEoN4W_BJNaFg1o6o07nP85vo7CqxuSHrrScjMriI3T7TTp1yHxTzhNeLXGDHHhZ9g_PCpNlNo7WU6D49W22BqhQ-3lRh5-b15E2mk-8H8n6jdWjB22xmU8DAl13P9nBzQlhRYqEAg7REQi2zqpNjQR4REZa1YsIJOZ74YMrmQCRsXo31sVcOR8t2q2pyd6bvWg3cna_MSNVzDkEmQKfxcCC392NnlTk_7QS0mGnMRKf9zXdEXBoV2- ....
It is interested the reference to common here even though i was using "Authority": "https://login.microsoftonline.com/{0}/v2.0" > where {0} is tenant mycompany.onmicrosoft.com
Guest users are related only to the particular tenant, so we need to give tenant id instead of common. Current Azure AD B2B common endpoint can't be used for guest users, guest users are treated as personal accounts.

Suggest OAuth flow(grant type) or approach for below requirement

CompanyA is integrating with CompanyB where CompanyA's users will be buying devices of CompanyB.
CompanyA wants to show user's device(CompanyB) details on their app by calling
CompanyB's API on each user login.
CompanyA user is authenticated on CompanyA IAM.
CompanyA has to call register device when user tries to add an device first time.
Help me to identify the flow which i can use to query particular loggedin user's device only.
Do i need to create duplicate user account on CompanyB's IAM?
If i use client credential flow for API to API call, access token given by CompanyB is only provides access for API calls but it does not tell that on behalf of correct user only call is invoked.
Assume that CompanyA uses IdentityServer or any other provider as IAM and CompanyB uses Azure AD B2C.
Any other approach?
Please see below diagram,
You should be able to do this by making the Company B API multi-tenant in their Azure AD.
There are other options surely, this is just the first one that came to my mind.
Overview of the multi-tenant pattern
You would have to do admin consent on it to get the API's service principal in your Azure AD tenant.
The Company B API can give you an endpoint for doing this, redirecting you with the proper parameters to the authorization endpoint. How to send a sign-in request
After doing this, you should be able to then require permissions on the API from Company A API in your tenant (configured in Azure AD).
Configure a client application to access web APIs
After doing those things, your API should be able to use On-Behalf-Of grant flow to get an access token for Company B API.
Using Azure AD On-Behalf-Of flow in an ASP.NET Core 2.0 API
Company B API must be configured to accept access tokens from another issuer than their Azure AD of course.
In general multi-tenant scenarios, the issuer validation is commonly turned off.
If Company B wishes to have control over this, currently they will have to explicitly list the valid issuers.
Issuer values look like this: https://sts.windows.net/31537af4-6d77-4bb9-a681-d2394888ea26/, the GUID is your Azure AD tenant id.
The Company B API can extract the tenant id and user object id from the access token, and authorize the user to resources based on them.
I was looking at the AWS side and looks like they have something that could meet the requirements
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_federated-users.html
Was wondering if something like this exists in Azure.

Configuring User Authorization in Client Applications

Background Explanation
When it comes to Identity Server 4, I come to a road block when i think about the design of user management in the client applications.
At this point, I have Identity Server setup using ASP Identity User Accounts as its user store.
I've built the UI for adding users to the Identity Server User Store.
I've tested setting up a client which is an MVC application, and I'm at the point where i can successfully authenticate with Identity Server and receive the openid identity token in my client application.
Identity Server is providing my client application with authentication.
Now, i need to concentrate on authorization within my app. This is where i get stuck, I need to create users local to the application, where user privileges within the application are stored.
I will need to link / associate the user in Identity Server to the user in the client application.
One way to do this would be to store the sub in the identity token as a user claim in the client application database (Asp Identity). This way, when a user authenticates i can locate them in the local db, based on the sub in the token.
The sub would have to be the user's unique id in the identity server user store. This way, if the user's email is changed, we can still link the two user accounts.
The user accounts in the client application wouldn't require passwords or email addresses, it would be purely claims and roles that are used for authorization across the application, as well as any other application specific information.
Question
Communication between Identity Server and the client application must need to exist when creating users in the client application?
We need to associate the two accounts?
We need to ensure that the client user account being created also has an Identity Server user account to be successfully authenticated?
When in the process should these tasks be complete? Im looking for some guidance in the flow of the communication between the two applications?
EDIT
Is it feasible that there are no User Accounts in the client application at all?
By this i mean that all user claims for a user are stored in the User store of Identity Server.
When a client authenticates with the IDP it requests only the user claims that are specific to the client application.
Example user claims in the User Store :-
"clientA_role" : "administrator"
"clientB_role" : "user"
When Client Application A authenticates, it requests only the scope clientA_role
This feels bad!
Any suggestions?
If you have many client applications then the way I recommend to do the user management is:
User Management Service:
Create a separate service for users management that identityserver will use as user store and applications will use as user repository when user metadata is needed.
Also why would you do something like:
Example user claims in the User Store :-
"clientA_role" : "administrator"
"clientB_role" : "user"
why not
just "roles": "user"? and in your application you will protect your resources using Authorize[Role] annotation.
do not create different fields for different applications, think of it as general user management service, I am pretty sure that standardizing your identity management will make it easier and will gain you maintainability and flexibility.
IdentityServer service handles identity management:
might be a good idea to keep user store inside the same service providing authorization if you feel that your application does not have such deep users management needs.
again in this case, store standard claims and return the claims you need inside an id_token or access-token.
Update:
For a specific user that have different roles in different applications:
let us say we have the following:
1- User1 has user role in first app and admin role in second app, then
User1.Roles{"FirstAppUser","SecondAppAdmin"}
2- User2 has admin role in both apps, then:
User2.Roles{"FirstAppAdmin","SecondAppAdmin"}

Devise and LDAP for users from specific organizations

I'm working on an application which clients are organizations; each organization has many employees, the users of the application. Not all the employees are users of the application, so each organization has a manager that sign up the employees that will be users.
One of our clients is asking us to use their LDAP authentication system, so that users don't have to learn a new login and password.
Currently, authentication is done using Devise. I've found an article in their wiki (https://github.com/plataformatec/devise/wiki/How-To:-Authenticate-via-LDAP) that explains how to add a new Warden strategy to deal with LDAP.
I've done a small modification so that if a user is authenticated by LDAP but not registered in the application, it will not create a new account for him, but show an invalid login message: https://gist.github.com/jdanielnd/a0e6a73f3f5f9b3462a6.
However this is the behavior I need: the organization model will have a flag for LDAP authentication and a LdapSettings object with the LDAP settings data.
If the user email belongs to a user in an organization that uses LDAP authentication, it will grap the LDAP settings from that organization and try to authenticate the user.
If the user email doesn't not belong to user in an organization that uses LDAP authentication, it tries to authenticate him against the database as usual.
I don't know much about Devise. Is it possible? Does anyone have any idea how can I achieve this?
Thanks!

Resources