While the Microsoft Graph API seems to be very complete feature wise, it seems like I am stuck at a fairly easy request. For a small web application I want to list apps that are registered in Azure. What a want to do with them is a little bit out of scope, but in the end I want to show the user some important applications (which we flag in some way - using tags or something like that) that the user has access to.
Now, using the /applications resource in the beta endpoint of the Graph API I can retrieve a list of applications. Now, the application does not need admin consent. When requesting the apps, it retrieves all registered apps, which is a bit odd I think. Why would it return all apps and not just the ones that are assigned to me?
But okay, lets move on. Now I have the list of apps (or the metadata of it). How can I determine if the signed-in user has access to this application (or it doesn't require assignment). Am I missing something or is this nowhere to be found?
You can use query parameters to customize responses. Please check the link https://learn.microsoft.com/en-in/graph/query-parameters
I have used appRoleAssignment with the neccessary parameters to retrieve all apps a user has access to. Turned out to be quite simple. Beta only, but stable.
Related
I have a microservice architecture, where one Single Page Application accesses three different APIs:
I am securing those APIs via the Microsoft Identity Platform and therefore I also need service principals.
My first approach matches with all the examples I found on blogs or in the MS docs.
In this case I have one app registration for the client app and three additional ones for the APIs:
This has the following impact:
Each API has its own audience.
I get four service principals for each application.
I get three different places where I have to administrate the user assignments to roles. (for example: User A can read assets from API A etc...)
This works, but comes also with some problems:
The other admins that are managing which user is allowed to do what are confused about three different places they have to assign roles. It would be nicer to have one central place.
The roles of the users are not placed in the ID tokens, because only roles of the client application would go there... but I do not want to assign permissions in the client app again.
If API A wants to call API B or C, I need two access tokens for other APIs.
This lead me to a second idea:
Here I have one registration for all 3 APIs. This already solves problem 1 and problem 2. But it also gives me a strange feeling, because I never found other people doing so.
Also my ID tokens are not telling me the roles, so to fix this, I could even go another step further to a single app registration for everything:
Now one registration exposes an API and consumes this API also. Something what is possible and seems to solve my problems. I even get all roles for the users in my ID tokens AND in my access tokens now.
However, this is contradictive to all other examples I found.
Which disadvantages does the last solution have?
Which of the three approaches should I chose?
Which disadvantages does the last solution have?
One thing that comes to my mind is that you want API A to be able to edit data in e.g. MS Graph API, so you give it the app permission to Read/Write Directory data.
Now with the shared app registration this permission has also been given to API B and API C.
So the principle of least privilege may be violated in the second and third options.
But it does make it easier to manage those APIs as you noticed.
The third option does open up the door for the user to acquire access tokens to any APIs that you might want to call on behalf of the current user from your APIs.
So if you wanted to API A to edit a user through MS Graph API on behalf of the user, you'd have to require the read/write users delegated permission (scope) for your app.
This would allow the user to acquire this token from your front-end as well, even though that is not intended.
Now they would not be able to do anything they wouldn't otherwise be able to do since the token's permissions are limited based on the user's permissions, so this might not be a significant disadvantage.
Which of the three approaches should I chose?
As with many things, it depends :)
If you want absolute least privilege for your services, option 1.
If you want easier management, I'd go with option 3 instead of 2.
There was that one thing I mentioned above about option 3 but that does not allow privilege escalation.
I'm writing an application that will be the backend for a react website. The website is to be used by our customers, but we will fully control the permissions of the user. We have decided to use Azure AD to secure requests, but will also be exposing the API for end users to use directly if desired.
My understanding is in Azure AD I will have to create an application that will allow web based implicit authentication (for the react site), as well as a native application that will allow a dameon based application to authenticate to the API.
This I believe means I will have two audience ids in my application.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Sorry I'm just totally lost and the documentation is beyond confusing given how frequently this appears to change!
TLDR: Do I need two applicaitons configured in azure ad, and if so whats the best way to set permissions (claims). Also is oAuth 2 the right choice here, or should I look at open id?
Right away I gotta fix one misunderstanding.
Daemon apps usually have to be registered as Web/API, i.e. publicClient: false.
That's because a native app can't have client secrets.
Of course the daemon can't run on a user's device then.
Since that's what a native app. An app that runs on a user's device.
This I believe means I will have two audience ids in my application.
You will have two applications, at least. If you want, the back-end and React front can share one app (with implicit flow enabled). And the daemon will need another registration.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
Yes, ids are included only. If you need names, you go to Graph API to get them. But why do you need them? For display? Otherwise, you need to be using the ids to setup permissions. Names always change and then your code breaks.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Your thoughts for multi-tenant scenarios are correct. If you did want to implement these though, I made an article on it: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Why would you need to setup the roles in multiple apps though? Wouldn't they only apply in the web app?
If the native app is a daemon, there is no user.
Overall, I can see your problem. You have people from other orgs, who want access to your app, but you want to control their access rights.
Honestly, the best way might be to make the app single-tenant in some tenant which you control. Then invite the external users there as guests (there's an API for this). Then you can assign them roles by using groups or appRoles.
If I misunderstood something, drop a comment and I'll fix up my answer.
Azure AD is of course a powerful system, though I also find the OAuth aspects confusing since these aspects are very mixed up:
Standards Based OAuth 2.0 and Open Id Connect
Microsoft Vendor Specific Behaviour
ROLE RELATED ANSWERS
This is not an area I know much about - Juunas seems like a great guy to help you with this.
OAUTH STANDARDS AND AZURE
I struggled through this a while back for a tutorial based OAuth blog I'm writing. Maybe some of the stuff I learned and wrote up is useful to you.
AZURE SPA AND API CODE SAMPLE
My sample shows how to use the Implicit Flow in an SPA to log the user in via Azure AD, then how to validate received tokens in a custom API:
Code Sample
Write Up
Not sure how much of this is relevant to your use case, but I hope it helps a little on the tech side of things...
Service or daemon authentication to the Microsoft Graph grants access to a limited number of functions.
For example, to be able to work with Planner and tasks, you have to be logged in as a user. In other case, we can't access most of user details, we can't access user's files and so on.
Why service or daemon must have more permissions then now? In our case, service should automatically create Planner tasks and Calendar events for specific users or groups according to automatically registered events. Sometimes it should also create or add or read files in OneDrive of this user. Also automatically, of course. Due to Microsoft Graph restrictions, it is easier to use additional 3rd-party service to track tasks, or even write our own. The same situation with files.
Microsoft Graph looks like a powerful API, but due to its access restrictions it becames unusable when you need to made something automatically, without any user actions.
What is the reason for most of these restrictions?
Is there any walkarounds?
Office 365 works perfect with deamon applications but not in your usecase. It works great for modifying a user' calendar for instance. See here https://learn.microsoft.com/en-us/graph/api/user-post-events?view=graph-rest-1.0&tabs=cs
Apart from that, if you want to have something changed in the graph api. The best way to let Microsoft know is to create an item on UserVoice. This is to let users influence what features they need, maybe you can express your wishes there. https://microsoftgraph.uservoice.com/forums/920506-microsoft-graph-feature-requests
Recently, YouTube decided to make video tags unavailable publicly. So to get the tags for a given video, I need to make an authenticated request to the API as the owner of the video. This is not a problem in my case as I'm fetching my own videos.
However, I'm confused about the authentication flow since YouTube strongly recommends to use OAuth2. Since I'm always going to authenticate as the same user (the owner of the video, aka myself), I definitely don't need to have any browser page for the actual user of the app to do anything. I see how I could have done it using ClientLogin (hardcoding login and password into the app) but I'm not sure how to approach this using OAuth2.
One last detail - that is not necessarily relevant since a high-level answer would be enough - is that I'm developing on iOS. Also I looked at this https://developers.google.com/accounts/docs/OAuth2 and particularly the web server case which seems closest to mine but was not able to get a clear idea from it.
Thanks in advance for your help and don't hesitate if you need me to be more specific.
There is no OAuth flow that supports your use case.
In general, you should not be distributing your YouTube login as part of your application. Even if this were available via ClientLogin, after a certain number of logins, you would likely be presented with a challenge because the authentication servers would detect a strange usage pattern.
OAuth is not for distribution a single user's login to a large N, where N is the number of users of your application. OAuth is meant for your application to act on behalf of an end user, and because tags are no longer exposed to end users through the UI, it does not make sense to expose them to users via the API either. More details can be found here:
http://apiblog.youtube.com/2012/08/video-tags-just-for-uploaders.html
How many videos do you have? What is the purpose for needing the tag metadata? From a pragmatic perspective, here are a few alternative implementations that would be easier and would not require users to log in as you:
Store a single file mapping video IDs to tags on a server somewhere and fetch this periodically. Google App Engine is a good place to do this.
Put the tag data in the description in a predictable format (you host the videos), and generate the metadata from this.
I am trying to develop a very basic console application that will retrieve a user's homepage (twitter updates from people followed by the user) and save it (json). I've read a lot on the internet, but still am unsure of whether i need to 'register' such an application, and if yes, how could I possibly do it for a console app.
I'd like to get a step-by-step rundown on how I should proceed with the development. Its just a tad complex for a noob like me in this field. I'm aware that off-the-shelf libraries for doing this job are aplenty, but I lack a general understanding of how I should approach this.
Much appreciated,
Abhi
The answer really depends on a few things.
If your application is not going to try to access information about protected users (users can opt to be protected so their information and tweets are kept private) your application will not need to be authorized by any user and will not need to be registered or deal with OAuth. Without using OAuth, you will be limited to making 150 requests per hour, per IP address.
If your application needs to make more than 150 requests an hour, or needs to access protected user information, then you will need to register your application and make requests on behalf of a user. This user could be your twitter account. This will give you up to 300 requests per hour per authorized user.
I can't give you much detail as to how to best write a console application with TweetSharp., but I am familiar with Twitterizer (I wrote it).