How does an admin grant access to an app? - azure-active-directory

I have made a web app that using Microsoft Graph and the scopes profile, openid, email and User.Read. This works fine.
I now want to include offline_access, User.Read, Mail.Send, Calendars.ReadWrite, Directory.ReadWrite.All, Directory.AccessAsUser.All, User.Read.All, Files.ReadWrite.All, Files.Read, Files.ReadWrite, and Sites.Read.All scopes.
When trying to login I get the message:
You can't access this application.
Tutorial Sample App needs permission to access resources in your organisation that only an admin can grant. Please ask an admin to grant permission to this app before you can use it.
I registered the app at https://apps.dev.microsoft.com/ and have these Graph Permissions set:
Using PHP, I use the following
use Microsoft\Graph\Graph;
use Microsoft\Graph\Model;
const CLIENT_ID = 'xxx';
const CLIENT_SECRET = 'xxx';
const REDIRECT_URI = 'xxxx';
const AUTHORITY_URL = 'https://login.microsoftonline.com/common';
const AUTHORIZE_ENDPOINT = '/oauth2/v2.0/authorize';
const TOKEN_ENDPOINT = '/oauth2/v2.0/token';
const SCOPES = 'profile openid email offline_access User.Read Mail.Send Calendars.ReadWrite Directory.ReadWrite.All Directory.AccessAsUser.All User.Read.All Files.ReadWrite.All Files.Read Files.ReadWrite Sites.Read.All';
and to create the authorisationUrl
$authorizationUrl = $provider->getAuthorizationUrl();
So, how can I get admin to grant access?

In order to obtain Admin Consent, you need to have an Admin for the tenant authenticate against the /adminconsent. The prototype for this URL is (line-break for readability only):
https://login.microsoftonline.com/common/adminconsent?
client_id=[APPLICATION ID]&redirect_uri=[REDIRECT URI]
I've written a blog post on this that will help walk you through how this works: v2 Endpoint and Admin Consent.

Related

Microsoft graph API: permission grant for application (app roles) (NOT delegate via Oauth2PermissionGrants)

We are using the Microsoft graph API (.net SDK).
We know that we can use GraphServiceClient.Oauth2PermissionGrants for delegated grant (in Azure AD app it's "Expose an API").
But when it comes to granting admin consent for application type (via app role of other applications), like below:
In the portal, we can just click "Grant admin consent for XXXX".
I could not figure out how to GraphServiceClient.PermissionGrants does not seem to be the one we are after.
Googled around, found the related answer Azure OAuth: Unable to programmatically create app with admin consent for permissions , which leads me to the actual API used https://learn.microsoft.com/en-us/graph/api/serviceprincipal-post-approleassignedto?view=graph-rest-1.0&tabs=csharp
In a nutshell, use app role assignment via AppRoleAssignedTo:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var appRoleAssignment = new AppRoleAssignment
{
PrincipalId = Guid.Parse("THE-OBJECT-ID-OF-THE-PRINCIPAL-OF-THE-AZURE-AD-APPLICATION-THAT-NEEDS-ACCESS"),
ResourceId = Guid.Parse("THE-OBJECT-ID-OF-THE-PRINCIPAL-OF-THE-AZURE-AD-APPLICATION-THAT-HAS-THE-APP-ROLE-DEFINED"),
AppRoleId = Guid.Parse("THE-ID-OF-THE-APP-ROLE-DEFINED-IN-THE-RESOURCE-ID-ABOVE")
};
await graphClient.ServicePrincipals["THE-OBJECT-ID-OF-THE-PRINCIPAL-OF-THE-AZURE-AD-APPLICATION-THAT-HAS-THE-APP-ROLE-DEFINED"].AppRoleAssignedTo
.Request()
.AddAsync(appRoleAssignment);

How to pre-create federated Azure AD (AAD) users in Azure AD B2C?

I have our main AAD federated to our Azure AD B2C using OpenID Connect. For metadata I'm using the following endpoint: https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration
This set up works fine when users are sign up. When a user signs up, a user is created in B2C. But I need to create these users in advance. For this purpose, I'm using Microsoft Graph APIs to create users. The following code creates a user in B2C but it is not correctly linked to AAD user. When I try to login with AAD user in B2C, it gives me following error
AADB2C99002: User does not exist. Please sign up before you can sign in.
var user = new User
{
AccountEnabled = true,
DisplayName = "Last, First",
Identities = new List<ObjectIdentity>()
{
new ObjectIdentity
{
SignInType = "federated",
Issuer = "https://login.microsoftonline.com/{tenant_id}/v2.0",
IssuerAssignedId = "{**unique_user_object_id_from_federated_active_directory**}"
}
},
PasswordPolicies = "DisablePasswordExpiration"
};
I demonstrated this scenario here in detail:
https://github.com/azure-ad-b2c/samples/tree/master/policies/link-local-account-with-federated-account

Integrate Azure AD with AngularJS and call CORS web api

After going through the article https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-angularjs-spa, we have created a web application named ToDoSpa and web api named ToGoApi registered in Azure Active Directory and are able to authenticate but the problem lies in consuming the web api including the endpoints as
AADSTS65001: The user or administrator has not consented to use the application with ID '2528e8f3' named 'ToDoSpa '. Send an interactive authorization request for this user and resource.
Trace ID: df70a02e-6a53-4899-8319-0ba440540500
Correlation ID: 699515a6-dccb-421e-92ae-e9b5a700ad1b
Timestamp: |interaction_required".
Client Id:
ToDoSpa->2528e8f3
ToGoApi->815933a4
In ToDoSpa,we have defined the scopes for the application ToDoSpa as "User.Read and Directory.Read.All" and authorized the client application using the client ID of web api(815933a4) in Expose API. In App permission, we have included ToDoSpa and have grant consent the application.
app.js
var endpoints = {
"https://graph.microsoft.com": "https://graph.microsoft.com",
"https://localhost:44392/api/weather": "https://firstupconsultants.onmicrosoft.com/ToGoApi"<!--localhost:App Id Uri of Server-->
};
adalProvider.init({
instance: 'https://login.microsoftonline.com/',
tenant: '<tenant-id>',
clientId: '<client-id of server>',
endpoints: endpoints,
extraQueryParameter: 'prompt=admin_consent'
}, $httpProvider);
}]);
//Get
weather1.getWeather = function () {
return $http.get("https://localhost:44392/api/weather").then(succeessCallback, failedCallback);
function succeessCallback(weather) {
//$scope.weather = weather.data;
weather1.items = weather.data;
}
function failedCallback(error) {
console.log("An error has occurred:", error);
}
}
web.config
<add key="ida:Tenant" value="<tenant-id>"/>
<add key="ida:Audience" value="https://firstupconsultants.onmicrosoft.com/ToGoApi"/>
<!--localhost:App Id Uri of Server-->
Typically, when you build an application that uses application permissions, the app requires a page or view on which the admin approves the app's permissions. This page can be part of the app's sign-in flow, part of the app's settings, or it can be a dedicated "connect" flow.
When you're ready to request permissions from the organization's admin, you can redirect the user to the Microsoft identity platform admin consent endpoint.
Here is sample URL for the same:
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
When you want to enable the users on other tenant can use the application, the application required to give the consent first. To do that you can make a HTTP request to grant the admin consent easily by using the prompt parameter.
You can read about this in detail in below doc:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#request-the-permissions-from-a-directory-admin
Additional reference:
https://blog.mastykarz.nl/implementing-admin-consent-multitenant-office-365-applications-implicit-oauth-flow/
Hope it helps.

AAD - Owner password credential flow

Hi I am trying to use owner password credential flow by giving username and password and it is giving below error. I am using the native application as the client Id.
UserPasswordCredential credentials = new UserPasswordCredential(_userName, _password);
AuthenticationContext authContext = new AuthenticationContext(_authority);
var accessToken = await authContext.AcquireTokenAsync(_apiResourceId, _clientId, credentials);
accessToken.AccessToken;
AdalServiceException: AADSTS65001: The user or administrator has not consented to use the application with ID 'xxxxxxxx' named 'nativeclient'. Send an interactive authorization request for this user and resource
I have a scenario where I cannot use client credential flow. Is there anything I am missing as when I use the powershell client ID 1950a258-227b-4e31-a9cf-717495945fc2 it works. How can I consent this application on the context of user as I am not the tenant admin.
It depends on whether the permissions you have added require admin-consent.
You can see it on Azure portal:
If the permissions require admin-consent, you have to use an admin account to do the consent by clicking "Grant admin consent for {your tenant}" here:
If the permissions don't require admin-consent, you just need to use a non-admin account to do the consent by accessing https://login.microsoftonline.com/{your tenant}/oauth2/authorize?client_id={Client ID}&response_type=code&redirect_uri={Reply URL}&resource={Resource you want to access, for example: https://graph.microsoft.com/}&prompt=consent.
Besides, could you please provide more details the "scenario where I cannot use client credential flow"?

Does what you send in Scope Governs whether you can login with Microsoft Account using Azure AD V2 Endpoints

I have registered a application using the App Registration (Preview) Blade and added the Azure Service Management API as API Permissions I downloaded the MSAL based Sample from
https://github.com/azure-samples/active-directory-dotnet-webapp-openidconnect-v2
Now in startup.auth.cs if i change the Scope i.e keep openid and add https://management.azure.com and then run and try and Login with a Microsoft Account i get the following error
This Doesn't Look like a Work or School Email you cant Sign-in here with Personal Account use your work or School Account Instead.
if i remove the Scope for https://managment.azure.com and just keep Openid profile offline_access i get the Consent Screen and Login
new OpenIdConnectAuthenticationOptions
{
// The Authority represents the v2.0 endpoint - https://login.microsoftonline.com/common/v2.0
// The Scope describes the initial permissions that your app will need. See https://azure.microsoft.com/documentation/articles/active-directory-v2-scopes/
ClientId = clientId,
Authority = String.Format(CultureInfo.InvariantCulture, aadInstance, "common", "/v2.0"),
RedirectUri = redirectUri,
Scope = "openid https://management.azure.com/.default",
PostLogoutRedirectUri = redirectUri,
I am Expecting to have the user Login and Obtain a Token for management API , i am Looking for Reasons for getting the above Error is this Expected ? The Account that i am using exists in my directory as a Member . this works if i use a Managed user(user#tenant.onmicrosoft.com) to Login
Since personal MS accounts cannot be used to manage Azure subscriptions unless they are added to an Azure AD, you should use the organizations endpoint instead of common.
In v1 "common" meant any AAD tenant.
In v2 "common" means any AAD tenant + any personal MS account.
If you wanted only personal accounts, you can use "consumers".
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc#fetch-the-openid-connect-metadata-document
You can use "organizations" to allow any AAD tenant but disallow MS accounts.
Of course a user can just edit the URL and login with a personal MS account anyway, so you'll want to check the tenant id of the logged in user.
The tenant id for MS accounts is always 9188040d-6c67-4c5b-b112-36a304b66dad, per the docs: https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens#payload-claims.
So check the idp claim.

Resources