I have dozens of Azure Active Directory API's and SPA's that talk to each other. Here is an example:
User - Has roles necessary to use SPA and API 1
SPA - Talks to API 1 using Delegated Permissions
API 1 - Talks to API 2 using Application Permissions
API 2
These SPA's and API's each have a single Application and Client ID in Azure Active Directory but they are multi-tenant, in that they serve internal users in multiple countries using Role Based Access Control (RBAC).
All of the above applications run internally but I have a new requirement that we need to hand over the SPA application to users external to the company and that they should not be able to see parts of the SPA for other tenants and also they must not be able to call API's for other tenants. How can this be achieved?
For your scenario, I think you can use Azure AD App roles for it.
For example:
You can create two roles in the Azure AD applicaiton for the SPA. One is Admin,who can access whole SPA site and API 1. One is User, who can only access part SPA and cannot access the API 1. Then you can assign roles to users.If you have AAD basic or Premuim , you can assign roles to groups.
After finishing this, you will get the roles information in id_token. So that you can give them different access to your SPA. The rest work should be built in your SPA to deliver different access to different users.
You can also read this blog written by joonas for more detials.
Addtional, this answer is just a solution as I thought, it may be a little different from your realtic scenario which I cannot test.
Hope this helps!
Related
Our current system contains two web applications with OAuth2 centralized user management. Application A is an OAuth client and application B is the OAuth provider. And application A is for internal users and application B is for external users as well as internal users.
To integrate with CIAM for external user onboarding, our system needs to call the user invitation API. That only can be done by application A due to some restriction. Is that doable as an external user will only have access to application B. To invoke CIAM APIs, the client needs to be registered with Azure application ID. That won’t be a problem if the same Azure app ID can be shared between two applications or the invitation could be for another application with a different Azure app ID.
• As you have said CIAM here, thus considering Azure AD B2C as the IdP and authorization provider, the application B that you have stated here which will act as an OAuth provider for application A thus resulting in it being a client and the other application being a provider. Thus, as a matter of fact, you cannot share tokens between the apps for inviting a user from one app to another app. Also, sharing the same application ID between two different applications registered in different tenants is also not possible.
• But you can acquire a token interactively on the second application, i.e., application B and once the silent call fails, then the interactive flow will rely on the Azure AD B2C session cookies to give the user Single sign-on. You can achieve the above said through configuring the Azure AD B2C session behaviour with regards to single sign-on on an application. This setting allows you to maintain a user session exclusively for an application, independent of other applications. For example, you can use this setting if you want the user to sign into Application B regardless of whether the user is already signed into Application A.
Thus, in this way, you can share a sign-in between two applications. For more information and details regarding this, kindly refer to the below documentation below: -
https://learn.microsoft.com/en-us/azure/active-directory-b2c/session-behavior?pivots=b2c-custom-policy#configure-azure-ad-b2c-session-behavior
ADB2C How to share user token between two different applications?
I am building an application which has a front-end (a SPA built with Vue.js) which interfaces to a couple json-based Web APIs in the back end (hosted in Azure). The Web APIs need to be secured via Azure Active Directory and users must be a member of a security group. Furthermore, the SPA should simply try to force the user to sign into an approved account if they are not signed in as one (i.e. just auto-redirect).
I actually have all this working. The AAD application has Group.Read.All, the user signs in via the SPA and gives consent, and the SPA calls getMemberGroups. Furthermore, the Web APIs can check the SPA-provided access token, and the Web APIs unfortunately must also call getMemberGroups.
And I think that is my concern. The Web APIs keep having to call getMemberGroups to lock it down. If I did the auth on the service, I could potentially only return an access token once membership groups has been verified. But then I lose the easy MSAL sign-in model in the SPA - the Web APIs don't actually provide any front end, the SPA is statically hosted.
As far as I can tell, I cannot get Azure Active Directory to create a token guaranteed to have certain group claims in it. I think this would solve my problem.
Can somebody offer some advice on the best way to design an auth model around a SPA + Web API environment? Or is the method I have taken the only way to do it?
Thanks!
You can 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": ["1ce9c55a-9826-4e32-871c-a8488144bb32"]
}
You can also leverage Role along with Groups to control access of your application. You can define some applciation roles and assign the roles to the groups. Then the users in the group will have the claim like below:
{
"roles": ["admin"]
}
Then you can implement your authorization logic based on the roles of the user.
Refer to https://joonasw.net/view/using-groups-vs-using-app-roles-in-azure-ad-apps and https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps for more details
I have a requirement to create an admin UI where I need to list all users registered on IdentityServer to start assigning permissions and roles. This application internally uses PolicyServer, but as a superadmin user, I would need to see all users registered on IdentityServer. Here IdentityServer is responsible for authentication and the other application that uses PolicyServer is responsible for the authorization.
Which is the correct way to proceed:
1- This admin UI application should be connected to the same database that IdentityServer uses to get all the users?
2 Or should I need to extend IdentityServer on this way?:
http://docs.identityserver.io/en/latest/topics/add_apis.html
I followed this issue here:
IdentityServer/IdentityServer3#2607
but still, it is not clear for me how to proceed on the question above.
Well, the users database is usually provided by ASP.NET Identity, not so Identity Server.
I had the same issue and I went on to develop the admin Web app in the same host as Identity Server, thus using the database connection to get to the users (and the API resources, clients, etc.).
I argue that this is the simplest way to achieve what you want. And still allows you to provide a complete API on your Identity Server for external apps. I also did that (for scenarios where client apps are allowed to view/edit the user profile, for example). The API was built using plain ASP.NET Core MVC.
I created a "Web app / API" app in our organization's "xxx.onmicrosoft.com" Azure Active Directory. The app's "Multi-tenanted" property has been set to "Yes".
We configured OpenID Connect (we use https://github.com/mitreid-connect/) to use the following URLs:
https://login.microsoftonline.com/common/oauth2/authorize
https://login.microsoftonline.com/common/oauth2/token
Please note that we used "common" in the URLs and we didn't use "xxx.onmicrosoft.com" because we want people from outside "xxx.onmicrosoft.com" to be able to authenticate and access our app.
With those settings, the people from xxx.onmicrosoft.com can properly authenticate and access the app.
However, when I use my personal live.com account (with username xxx#gmail.com) to access the app, I get AADSTS50020 error. I am able to properly authenticate with my xxx#gmail.com account, but I do not get redirected to the Reply URL. I'm stuck on Microsoft's Web page with the following error msg:
AADSTS50020: User account 'xxx#gmail.com' from identity provider
'live.com' does not exist in tenant 'xxx.onmicrosoft.com' and cannot
access the application '391e7103-ZZZZ-zz87-xxxx-7xxxxxd5xxxx' in that
tenant. The account needs to be added as an external user in the
tenant first. Sign out and sign in again with a different Azure Active
Directory user account.
What configuration do I need to change if I want people from any identity provider to be able to access my app ?
Like it has been stated here, I expected that people from anywhere could access my app without requiring more configuration on my side.
I'm asking this question because I'm in the process of getting certified for AppSource and this currently blocks me from being able to do so.
AppSource only requires work accounts to sign-in. You are using an #gmail account - which is a personal account - and because you are using the Azure Active Directory v1 endpoint in addition to common (https://login.microsoftonline.com/common), it can't accept personal accounts to sign-in directly - only work accounts.
You have three options:
If sign-in personal accounts is not a requirement for your application, then you can continue using the v1 endpoint and use a work account to sign-in/test your application. This will make you ready for AppSource certification.
If you need/ want to allow personal accounts in your application in addition to work accounts, then you can consider using the v2 endpoint (https://login.microsoftonline.com/common/v2.0) for Azure Active Directory. The v2 endpoint allow both personal accounts and work accounts to sign-in with no effort.A note is the v2 endpoint has some limitations: if you can live with these limitations (for example, your application only needs to sign-in users and eventually make queries against Graph API), then in general it should be fine to use, but if you need extra features like protecting your own Web API with scopes, then this feature is not released at this point (as November 2017). Please read this document for an updated list of limitations of the v2 endpoint.
A third (but less recommended option for AppSource) is to keep using the v1 endpoint and make your application to be single tenant - which is to change the endpoint from https://login.microsoftonline.com/common to https://login.microsoftonline.com/{yourtenantid}, and then use B2B invitations API to invite every external users (including work and personal accounts) to be part of your Azure AD tenant/organization. More information about B2B here as well.
The option '3' above have some consequences for management as well for AppSource: by using this option, you are required to have one Azure Active Directory tenant (if you don't have a tenant already, you can get one using these instructions), and the users being invited will be guests accounts of this tenant - this mean that you need to invite every external user to your application/ tenant. A multi-tenant application allows any user from any organization to sign-in to your application with less management on your side. In general for SaaS applications, multi-tenant configuration is recommended.
For AppSource, also the option '3' leads to a less-immersive user experience (Partner led trial), where the end user won't be able to access your application's demo right away - mainly because that they have to wait for the invitation's email and accept it (user has to accept being guest of your tenant) so that they can access your application.
For more information about AppSource requirements and trial options - please see this article.
I am wondering what the best approach is for handling multiple environments with Azure Active Directory. Is the only way to do this to add an application for the WebAPI and clients for each environment. So for local I would have a localhost-webapi with a sign on like https://localhost/webapi and a client https://localhost/sample that has permissions to https://localhost/webapi. I would then need to do the same for the rest of the environments (dev,test,prod)?
If I understand your question correctly you have the following Setup:
In AAD, you have a single tenant where there is a single Web API registered.
In the same tenant, you have multiple, equivalent client applications registered, which correlate to the different environments you have set-up on your end.
This seems like the correct approach for testing multiple environments. Note that you could register different permission scopes on your Web API to represent permissions that each environment has to your API.
Thus you could have "user_impersonation_dev", "user_impersonation_test", "user_impersonation" and have each of your different applications request those specific permissions to your API. This might help for a cleaner set-up when doing development.