Background
I have a Web API registered in Azure AD and secured using WindowsAzureActiveDirectoryBearerAuthentication (OAuth2 bearer token). This is a B2B-type scenario where there are no interactive users - the applications calling the API are daemon-like background apps. As such, I don't need any consent experience - I just want trusted applications to be able to call the API, and other applications - even if they present a valid OAuth token - to be denied.
What I've tried
This sample seemed to describe my scenario almost exactly. However, the way it determines if a caller is a trusted app or not is by comparing the clientID presented via a claim by the caller to a hard-coded value. Obviously you could store the list of trusted clientIDs externally instead of hardcoding, but it seems like I should be able to accomplish this via configuration in the AAD portal so that a) I don't have to maintain a list of clientIDs, and b) I don't have to write my own authorization logic.
It seems like I should be able to define a permission for my API, grant that permission to each calling app in AAD (or a one-time admin consent), and then in my API just check for the presence of that permission in the scp claim.
From looking at the portal it seems like this is what Application Permissions are intended for:
I can create a permission just fine via the application manifest. Unfortunately, I can't figure out how to specify that it's an Application Permission, not a Delegated Permission! I tried changing the type from User to Admin as described on MSDN, but that seemed to have no effect.
"oauth2Permissions": [
{
...
"type": "Admin",
...
}
Question
Am I correct that Application Permissions are the best solution for my scenario? If so, how do I configure it? Or, as I fear, is this yet another feature that is On The Roadmap™ but not currently functional?
Ben, Application Permissions are declared in the appRoles section of the manifest. Indeed, if you declare an appRole called say 'trusted' in your resource application's (storage broker demo) manifest - it will show up in the Application Permissions drop down there. Then, when you assign that Application Permission to the client app - the access token that the client app will receive using the client credentials OAuth flow will contain a roles claim with value 'trusted'. Other apps in the tenant will also be able to get an access token for your resource app - but they wont have the 'trusted' roles claim. See this blog post for details: http://www.dushyantgill.com/blog/2014/12/10/roles-based-access-control-in-cloud-applications-using-azure-ad/
Finally, the above way to assign an application permission to a client app only works when both the resource and client application are declared in the same directory - if however these apps are multi-tenant and a customer will install these apps separately - a global admin from customer's directory will need to consent to the client app - which will result in the application permission getting assigned to the instance of client app in the customer's tenant. (my blog post covers this too)
Hope this helps.
ps: if you're stuck - feel free to ping me on the contact page of http://www.dushyantgill.com/blog
Related
I am currently developing a Microsoft Teams tab app using Teams Toolkit.
The users of the app should be able to invite guest users to certain teams and edit some of the users information in AD. This requires higher permission level than the users have.
I have tried to use delegated permission but this limits the permission of the app based on the user's permissions. See https://learn.microsoft.com/en-us/graph/auth/auth-concepts
Is there a way using Teams Toolkit or, as a last resort, some other package to get a Graph API token that will allow the app to perform operations that requires permissions higher that what the user have?
For reference I list below some of the permission the app needs:
"User.ReadBasic.All",
"Sites.ReadWrite.All",
"Domain.ReadWrite.All",
"Directory.ReadWrite.All",
"TeamMember.ReadWrite.All",
"TeamSettings.ReadWrite.All",
Thank you!
Just as Hilton mentioned, you should use "Application" permission for your scenario.
"Application" permission is designed to running from backend, so you can setup a backend web app or Azure Function to do this.
Here are the basic steps:
Go to your AAD app, and add the permission you want
Consent the permission
copy client id and client secret from AAD portal
Follow the steps to get access token
https://learn.microsoft.com/en-us/graph/auth-v2-service#4-get-an-access-token
By the way, recommend to use Azure Function features inside Teams Toolkit, which can help you easily setup an Azure Function in you Teams Tab project, then you can write the code inside the Azure Function to call graph api with application permission
There are two main types of permissions, as you've seen. The first is "Delegated", which basically means the user is "delegating" your app to do something on his/her behalf. This is of course limited to what the user themselves can/can't do, as it's basically just doing it for them. To do something -differently-, or to do without having that specific user associated with it, you need to use Application permissions. In this case, your access is essentially unlimited, BUT it means that a tenant administrator needs to consent upfront (i.e. once-off) to your application having this level of access.
"Application" permissions are therefore what you're needing in your scenario.
I'm trying to create an app within the Azure app management portal that will serve as a template to be used with any tenant. Basically what we are trying to do, is create a connector that will be approved using admin consent, and receive application level permissions to read all the emails in the organization using Graph API.
What I have managed to do so far is create an app within our own tenant and get application level permissions for this tenant only. This enabled me to successfully read all emails in my organization only (which is not possible using delegated permissions).
What is the right way to receive application level permissions for any tenant, using admin consent? Is the only way to do it, for the specific tenant to manually add an application that will receive admin consent?
I am using django with the social_core module.
Something does not add up...
Thanks.
You can register a single application (with a single client ID and set of credentials that you control), configure the permissions you desire/require, and then customers from different tenants can each grant admin consent for your application, in their own tenant.
If your application/service does not have a sign-in experience (i.e. it is exclusively used as a background service and users never sign in to it), you can construct the admin consent URL, such as:
https://login.microsoftonline.com/organizations/v2.0/adminconsent
?client_id={client_id}&scope=.default&redirect_uri={your_redirect_url}
You can read more about the admin consent endpoint at: https://learn.microsoft.com/azure/active-directory/develop/v2-admin-consent
I want to use azure active directory as my authentication provider for my Spring boot application. Which seems to be quite easy as long as you've got either admin rights yourself or you know someone with admin rights who can give you permission for the tickbox "Directory.AccessAsUser.All". Unfortunatly I dont have that. I know due to other successful projetcs that azure itself gives the oppertunity to still act as an authentication provider even without given any permission to the API Call permission section.
When I start the Server and go on localhost:8080/home whilst tracking my network traffic I can see in the Autherization file the following scope: openid profile https://graph.microsoft.com/User.Read https://graph.microsoft.com/Directory.AccessAsUser.All
So My Idea of Handling this is to reducing the scope of the Authorization request spring is asking for, to meet the authorization scope which I allowed in azure. Which is all of them but the last one as mentioned before.
I tried to configure the scope in my application.propertie with the following: spring.security.oauth2.client.registration.azure.scope=openid
So what happens is after im trying to access my application online im redirected to the mircosoft login page. After putting in my details im getting this:
In order to be able to access resources in your organization, requires authorization that only an administrator can grant. Ask
an administrator to grant permission for this app so that you can use
the app.
Has anyone an Idea of how to handle this?
I'd be greatfull for any help!
I think you can only log in as an administrator, because you are using the SDK provided by Microsoft when you log in, so you cannot customize the scope of permissions in application.propertie.
When you log in to the application, it will require you to consent to all permissions. If you just log in as a user, you cannot consent to all permissions. So, at least in the login module, I think it cannot meet your requirements.
Usually we can customize the scope of permissions only when requesting an access token. For example, if you only need to read user permissions, you can set: scope: https://graph.microsoft.com/User.Read .
Login sample.
Ok, I found the Problem. In my application.property I had this line of code azure.activedirectory.user-group.allowed-groups=. That was reponsible for the bigger scope. After deleting it everything worked fine.
I am trying to run the active-directory-dotnet-webapi-onbehalfof sample in single tenant mode. I've registered the web app service and the native app client as global admin for the tenant. When I run the sample, as a user in the tenant, I can get a token in the client only after consent pops up (first-time for user), and then call makes it to the service, but there it fails with below. Why is that? Documentation says that when a tenant admin registers the application no further consent is needed? I don't think it is possible to give consent when a remote webapi tries to get OBO token. Something seems buggy... AAD team, please clarify how the OBO feature should be used.
AADSTS65001: The user or administrator has not consented to use the application with ID 'b824502e-fe8a-4770-bd98-8d65a07efcc3'. Send an interactive authorization request for this user and resource.
Trace ID: ad7843d0-be4e-4098-8f7c-43c8e5505cfc
Correlation ID: 140466a4-7250-429f-8843-dbd4f63dc60e
Timestamp: 2016-11-25 21:46:13Z
When you register an application using the Azure Management Portal (manage.windowsazure.com) as a tenant administrator, then yes you should not get consent, as long as subsequent tokens are being retrieved in that same tenant.
Because you are seeing consent for the native client app, and then getting that error message, we must assume that something is not being satisfied which would suppress consent for your app.
To resolve this issue, my recommendation is to simply initiate an interactive authorization request just like the error message implies. You can do this by generating a log-in url for your application, with a specific query string that will force prompt tenant wide consent (prompt=admin_consent).
Here is the skeleton for the URL you need to complete:
https://login.microsoftonline.com/<TenantID>/oauth2/authorize?client_id=<AppID>&response_type=code&redirect_uri=<RedirectURI>&resource=<ResourceURI>&prompt=admin_consent
You can do this for all the applications you registered, and you should not run into consent issues (assuming you are indeed signing in as a tenant admin).
I hope this resolves your issue.
We're trying to figure out how to submit to the marketplace, but are not sure what we need to do to alter our existing signup flow to accomodate the SSO requirement
Our app was not originally built to be a marketplace app so our signup flow is built for individual users. We are already following the OAuth2 flow as outlined on this documentation page. However, its not clear to me how this works for an entire org when installing from the context of a marketplace app.
Does the admin grant access to all the individual scopes we currently request for the entire org at once? Is there need for some sort of service account or something since we currently are requesting offline access? I'd like to understand what changes we need to make to our server's signup flow in or whether it is just a scope / manifest mismatch.
We currently request the following scopes from an individual user when signing up.
['email', 'profile' ,'https://mail.google.com/', 'https://www.googleapis.com/auth/calendar'],
Exact questions are...
What (if anything) do we need to do to alter our current individual-focused signup flow to accommodate a Google Apps Admin signing up their whole domain?
What scopes do we need to in our Google Apps Admin listing and how do they relate to the scopes we currently request from individuals?
There are not so many changes if you are already using three legged OAuth2.
The first change would be in you project in the developer console. There you need to enable the Marketplace SDK and make the necessary configurations. Here you will add the scopes that your app will request and those are the scopes that the admin will see when installing the app.
The admin will see the scopes your app is requesting, and he will decide if it's ok to install the application in the domain. If it is approved, then yes, the admin would grant access to the entire domain.
Offline access is part of the Oauth flow, after you receive the refresh token, you can continue refreshing the access token without having the user to grant access again.
It is not necessary to have a service account. The service account has two purposes:
To manage information related to the application. In this case the service account can have access to it's own drive to store and retrieve information that is related to the app functionality.
Impersonation of users. When using domain delegation of authority, you can use a service account to impersonate any user in a domain and act on it's behalf to make API calls.
To deploy your app, you also have to create a new project in the Chrome Web Store, with a manifest for Marketplace.
To answer your questions:
It's not necessary that you modify your current oauth flow. The admin will install the app in the domain, but when a user access to the app, the process for authentication is the same as individual.
The scopes in your Marketplace SDK configuration should match the scopes your app will use. This is mostly for security reasons, it wouldn't be safe if you install an app with some scopes and then the app uses different scopes.
You can try your app before actually deploying it by adding trusted testers in the chrome web store dashboard or in the Console API configuration. This way you can check if your flows and all the configurations were done correctly.
Hope this helps. Let me know if you have more questions.