Office 365 OAuth: Necessary parameters to access mail with "client_credentials" - azure

I am struggling to write a standalone Java backend application which must access an Office 365 mailbox (Outlook mail from MS365 Family account) thru IMAP.
The used OAuth parameters are:
String oAuthAuthorizationURL = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token/";
String oAuthAuthorizationScope = "https://outlook.office365.com/.default";
The OAuth application type is defined as:
Personal Microsoft account users
The API permissions (Graph API) are set to:
IMAP.AccessAsUser.All
Mail.ReadWrite
offline_access
openid
POP.AccessAsUser.All
User.Read
In the application I do get a Bearer Token which is then passed to Jakarta Mail connect() to outlook.office365.com:993.
The result is:
A1 AUTHENTICATE XOAUTH2 dXNlcj1hbmR5....................RWpfQncBAQ==
A1 NO AUTHENTICATE failed.
What am I doing wrong?
Thanks

• Ensure that you have created a ‘client secret’ and mentioned it accordingly in your Java backend application, to access the Office365 mailbox through the Azure AD application registered in Azure AD.
To configure a Java backend application with a client ID and relevant secret, kindly refer to the below link: -
https://www.javainuse.com/spring/springboot-oauth2-client-grant
Then, ensure that the below ‘Application Permissions’ are added under ‘Microsoft Graph’ as API permissions for the Azure AD application: -
Delegated (Work or school account): - Directory.Read.All Application: - Domain.Read.All, Domain.ReadWrite.All, Directory.Read.All
• Also, since you are using Jakarta Mail Connect as a federated app which uses the token from Azure AD to access the Office365 mailboxes, you would need to grant the ‘Delegated Permission’ for ‘EWS.AccessAsUser.All’ under ‘EWS’ section as below as these permissions are necessary for accessing the Office 365 Exchange mailboxes through client credentials flow: -
Also, ensure that ‘Mail.Read, Mail.ReadBasic, Mail.ReadBasic.All, Mail.ReadWrite, Mail.Send, MailboxSettings.Read, MailboxSettings.ReadWrite, Calenders.Read, Calenders.ReadWrite, Contacts.Read, Contacts.ReadWrite’ delegated permissions are assigned to Microsoft Graph API for that Azure AD app registered.
Thus, when you configure the above, successful authentication should happen for your Jakarta Mailconnect app through Java backend application.
For more information, kindly refer to the below link: -
https://learn.microsoft.com/en-us/answers/questions/658248/azure-applicaiton-for-access-to-from-specific-appl.html

Related

Login from Microsoft account not working for Multitenant Azure AD application

I'm building multitenant SaaS web based application. Application is registered in my tenant and each customer with their office 365 subscription will get Service principal object in Azure AD.
I'm having problem with login from external account (Microsoft account) in customer tenant.
I created example and tried to see what I can get from access token.
Sample consists from one client application (.js) that uses MSAL library to handle authentication and two APIs that have protected endpoints. I also created three separate Azure AD applications AlanClient, AlanAPI1, AlanAPI2. Both AlanAPI1 and AlanAPI2 have API exposed (Expose an API section in Azure Portal application) and have specified one consumer AlanClient. AlanClient has permission to both APIs. All applications are registered with "accessTokenAcceptedVersion": 2 and "signInAudience": "AzureADMultipleOrgs".
As far as I understood this should be enough to login with
Office 365 account from host tenant
Microsoft account that is registered as external user in host tenant
Office 365 account from guest tenant
Microsoft account that is registered as external user in guest tenant
Clarification:
- host tenant --> Azure AD instance in which application is registered. In error message bellow tenant A.
- guest tenant --> Azure AD instance that is only using application
I have a problem with case no. 4
I get this error message:
AADSTS50020: User account 'lovro.p365#...' from identity provider 'live.com' does not exist in tenant 'A' and cannot access the application AlanClient 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 AD user account.
The scenes of 2 and 4 should be the same.
I have tested both and everything is OK.
You could use OAuth 2.0 auth code grant flow to have a test with it.
Construct a request to login.microsoftonline.com with your app configurations.
This URL will look like:
https://login.microsoftonline.com/[tenant A]/oauth2/v2.0/authorize?client_id=[client id of the Azure AD app registered in host tenant]&response_type=code&redirect_uri=[redirect uri of the Azure AD app]&nonce=1234&resource=https://graph.microsoft.com.
After signing in with credentials of Microsoft Account in tenant A, you will get a "code" in the address bar. Use this code to request access token:
POST /[tenant]/oauth2/v2.0/token HTTP/1.1
client_id=[client id of the Azure AD app registered in host tenant]
&scope=https://graph.microsoft.com/user.read
&code=[code got from the previous step]
&redirect_uri=[redirect uri of the Azure AD app]
&grant_type=authorization_code
Then we could get the access token for Microsoft Account as a guest user in tenant A.

Unable to use tenant-specific endpoint when authenticating personal MS accounts using Azure AD

We would like our customers to be able to authenticate using either personal or work accounts. We have set up a seperate AD in Azure to which customers are invited which should grant them access to our application.
In the ASP.NET Core application https://login.microsoftonline.com/{myTenantID}/v2.0 is used as authentication endpoint. A client id and secret from an application registered in the preview app registration through the portal is provided with the request. Authenticating our work accounts works smoothly, but when attempting to authenticate most personal accounts an error message is returned: An error was encountered while handling the remote login. AADSTS50020: MSA guest token redemption attempt on v2 common endpoint.
Should it not be possible to authenticate a MSA using a tenant-specific endpoint (only /common)?
Similar problem: Azure AD B2B Authentication error for users with custom domains - AADSTS65005: Using application 'My Application' is currently not supported
Also, this comment points out that authenticating MSAs in multi-tenant apps will not work, however, ours should be sigle-tenant:
https://github.com/Azure-Samples/active-directory-dotnet-webapp-roleclaims/issues/10#issuecomment-145125080
You need to use common endpoint if you are targeting both B2C and B2B using v2 endpoint for both work and personal emails to be able to call Azure AD protected endpoints.

Credentials prompt for access to Azure management APIs

I've been using the Azure fluent management APIs (https://github.com/Azure/azure-libraries-for-net) with some success in .NET Core.
However, I want to prompt the user to enter some credentials for a Microsoft account. Those credentials would have access to one or more Azure tenants / subscriptions, so I'd like to be able to use the result to browse and manage resources there.
This is something very close to what I would believe Azure Data Studio does: you can enter some Azure creds, and your resources will appear in the app.
I'm trying to understand the best approach for this. There seem to be a billion sites out there when you talk about Azure AD app registrations, but I haven't found a fruitful specific search query yet. I know I can register an app, get a client ID and client secret. I know I can set it to be usable by organisational accounts in the current tenant, or all tenants.
I can add the "Azure Service Management (delegated permissions : user_impersonation)" permission to my API permissions section for the app, but what's next?
If I use Microsoft.Identity.Client (as in https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon), I run into some questions:
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync! Nope, AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
I don't know what scope I want. https://management.azure.com/user_impersonation is apparently invalid.. https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs.. and my account (for instance) is associated with 3 tenants or 5 different tenants / directories - so how do I choose?
That's just what I've tried, the appropriate route might be a different one. In summary: I want a .NET Core Console app to request user credentials, and then get access to the Azure resources they have access to, in order to perform some resource management.
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
You are using the OAuth 2.0 client credentials grant to access web-hosted resources by using the identity of an application. This type of grant commonly is used for server-to-server interactions that must run in the background, without immediate interaction with a user .
AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
Azure AD provide two service : Azure AD V1.0 and Azure AD V2.0 . Please refer to Comparing the Azure AD v2.0 endpoint with the v1.0 endpoint . You can't use v1 token to acquire v2's token in a on-behalf-of flow .
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync
AS pointed above , That function is used to acquire an access token for this application (usually a Web API) from the authority configured in the application, in order to access another downstream protected Web API on behalf of a user using the OAuth 2.0 On-Behalf-Of flow. So you can't use app token which acquire using Client Credential flow .
https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
You are using the Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow , when sending a POST request to the /token v2.0 endpoint ,the scope should be :
The value passed for the scope parameter in this request should be the resource identifier (Application ID URI) of the resource you want, affixed with the .default suffix. For the Microsoft Graph example, the value is https://graph.microsoft.com/.default. This value informs the v2.0 endpoint that of all the direct application permissions you have configured for your app, it should issue a token for the ones associated with the resource you want to use.
Please check the Get a tokensection in above document .
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs..
AFAIK , currently Azure AD V2.0 apps can use:
Its own API
Microsoft Outlook APIs
Microsoft Graph API
Azure AD V2.0 currently doesn't support Azure management APIs .
So you problem is you need to allows work and school accounts from Azure AD and personal Microsoft accounts (MSA) which works with Azure AD V2.0 , but you can't use Azure management APIs . You can use Azure management APIs in Azure AD V1.0 but it allows only work and school accounts to sign in to your application , unless you invite Microsoft accounts as guest user in Azure AD V1.0 ,but you need to configure to point to the tenant-specific endpoint :https://login.microsoftonline.com/{TenantId_or_Name}). during authentication if you want to login with MSA in v1.0 apps.
Update:
You can use Code flow and azure ad v1.0 endpoint , user will be redirect to AAD's login page and enter their credential. Here is code sample for .net Core .
With Azure AD V1.0 endpoint , requests are sent to an endpoint that multiplexes across all Azure AD tenants: https://login.microsoftonline.com/common . When Azure AD receives a request on the /common endpoint, it signs the user in and, as a consequence, discovers which tenant the user is from. See document here . But in this scenerio ,you can only use work and school accounts(AAD) account to login .
The code sample in your link is using Azure Service Principal for Authentication , no interactive user login . You can use OpenID Connect Owin Middleware for authentication in .net Core applications as shown here .

AAD Multitenant App support login for all microsoft account

I am trying to create a multi-tenant application in Azure AD, which can login all users like Microsoft live/hotmail and also get the access permissions to access their management resource apis. I can get work accounts from other domain login but not live account. I get this error-
User account 'mitesh_***#live.com' from identity provider 'live.com' does not exist in tenant 'Default Directory' and cannot access the application '382dfccb-33af-4567-90cd********' 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.
I have heard of MSAL v2 endpoint to login both type of accounts, but I heard that this endpoint doesnt support permissions to access Resource management libraries yet.
Is there any way to achieve this with ADAL or any other way?
Thanks,
Mitesh
The azure ad v2.0 endpoint supports both personal Microsoft accounts and work accounts from Azure Active Directory . But the v2.0 endpoint issues access tokens only for:
-The app that requested the token. An app can acquire an access token for itself, if the logical app is composed of several different components or tiers.
-The Outlook Mail, Calendar, and Contacts REST APIs, all of which are located at https://outlook.office.com.
-Microsoft Graph APIs. You can learn more about Microsoft Graph and the data that is available to you.
v2.0 endpoint doesn't support management apis .And azure ad v1.0 endpoint it supports work accounts unless Microsoft accounts are added as an external user in the tenant first . In my opinion , currently there is no other ways or workaround to achieve your requirement .

Azure AD and Office 365 authorization/authentication flow

I've a silly doubt related to Azure AD authentication and Office 365 provider hosted app/add-in authentication.As mainly there are two authentication ways for Azure AD resource access
Authorization Grant flow ( user based /delegated permission )
Client Credential flow (app-only /admin consent)
Which of above is used by provider hosted add-in for Authorization/Authentication?
If none of the above,then what kind of flow it uses to authorize/authenticate users against Azure AD?
Under the permission section of provider hosted add-in ,there is a check box for app only.Is it same as Client Credential flow app-only or related to Azure AD app-only grant flow by any other way?

Resources