Office 365 APIs Microsoft Graph authentication failed - c#

I registered sample app from Microsoft graph sample app
And standard login is working but when I try to make it simplier by using this code:
var authContext = new AuthenticationContext(Settings.AzureADAuthority);
var token = authContext.AcquireToken(Settings.O365UnifiedAPIResource, new ClientCredential(Settings.ClientId, Settings.ClientSecret)).AccessToken;
I get the following error: Application with identifier '[ClientId here]' was not found in the directory microsoft.com
Setting.O365UnifiedAPIResource = #"https://graph.microsoft.com/";
Settings.AzureADAuthority = #"https://login.microsoftonline.com/common";
Does anyone know what can be the problem?

Settings.AzureADAuthority = #"https://login.microsoftonline.com/{tenant_id or tenant_name}";
When acquiring the token by using the client credential (client id + client secret). You should specify the tenant explicitly.
For example:
https://login.microsoftonline.com/{tenant_id}
or
https://login.microsoftonline.com/{your_domain.onmicrosoft.com}
BTW, as this registration will be for the sample app, it will only have the Mail.Send permission which is delegated permission. To acquire the app token, you also need to grant the app level permission in Azure AD since your are acquiring the app token rather than the user token.

Related

Authenticating EWS using Oauth with full_access_as_user

I'm trying to get an application using EWS to work against O365 with OAuth. I've managed to get it working in the case where I register the app in AAD, and grant it full_access_as_app (Use Exchange Web Services with full access to all mailboxes) in the portal. The code looks like this:
string tokenUri = "https://login.microsoftonline.com/TENANTID/oauth2/v2.0/token";
string resource = "https://outlook.office365.com";
string appId = "APPID_FROM_AAD";
var context = new AuthenticationContext(tokenUri);
X509Certificate2 cert = GetLocalCertificate(THUMBPRINT);
ClientAssertionCertificate c = new ClientAssertionCertificate(appId, cert);
AuthenticationResult authenticationResult = context.AcquireTokenAsync(resource, c).ConfigureAwait(false).GetAwaiter().GetResult();
m_exchangeService.Credentials = new OAuthCredentials(authenticationResult.AccessToken);
//all the autodiscover URIs for O365 are the same
m_exchangeService.Url = new Uri(#"https://outlook.office365.com/EWS/Exchange.asmx");
m_exchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, m_emailAddress);
This seemed a little extreme though. The application is a back end service, and only needs access to one mailbox (the impersonated user id), so I wanted to change it over to full_access_as_user permissions (Access mailboxes as the signed-in user via Exchange Web Services). I added the permission to the app, and then added the application to the user, but I got a 401 anytime I tried to operate on the mailbox after impersonation. I checked the JWT, and while with the original permission I had "full_access_as_app" in the roles, I didn't have any roles assigned this time.
Is there a way I can modify this so that I can have an admin add EWS access to one or more mailboxes in a tenant, or is the only way to get this to work to give an app access to every mailbox on the service?
Yes, OAuth authentication for EWS is only available in Exchange as part of Office 365. EWS applications require the "Full access to user's mailbox" permission.
Reference - Authenticate an EWS application by using OAuth

Embedding power BI report into web app – Error acquiring token

Embedding power BI report into web app – Error acquiring token
I have a .NET framework Web Application which uses Azure AD to authenticate the users. This is within an app registration which is of type 'Web app/API'
Within the web app I am trying to embed a power BI report from a master account (which has MFA enabled) so that users can see the report without having to login.
I am having trouble when trying to acquire a token using this code:
var credential = new UserPasswordCredential(username, password);
//// Authenticate using created credentials
var authenticationContext = new AuthenticationContext(AuthorityUrl);
var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential);
I am getting this exception message:
Message = "AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access
The IT admin will not remove MFA from the master account.
Is there another method I can use to embed the report into my web app without the user having to login and without removing the MFA from the master account? Or a way around the MFA issue?
Note: I have granted access to ‘Azure AD’ and ‘Power BI Api’ within the app registration.
Note: I have tried creating a new app registration of type 'native' and still get the same error.

Azure AD authentication failing when using ms live accounts other than my AAD acount

I trying to read user data from their Microsoft live account. I have written code as below:
public void GetUserData(){
var authContext = new AuthenticationContext("https://login.microsoftonline.com/common/");
var result = _authenticationContext
.AcquireTokenAsync("https://graph.microsoft.com", "<my client/app ID>", "<redirect URI>", new PlatformParameters(PromptBehavior.RefreshSession))
.Result;
var accessToken = result.AccessToken;
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",accessToken);
var userResponse = httpClient.GetStringAsync("https://graph.microsoft.com/beta/me/").Result;
//DO SOMTHING WITH DATA
}
my code is working fine when I used my AAD credentials, but when I used my personal account it is giving the following error.
AADSTS50020: User account 'XXXX#outlook.com' from identity provider
'live.com' does not exist in tenant 'Default Directory' and cannot
access the application 'XXXXXXXXXXXXXXXXX' 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.
Here is the screenshot:
It's similar to this question. could someone help me out?
v1 endpoints require that the user is a member in a directory.
You should probably use the v2.0 endpoints for this: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-appmodel-v2-overview
If you expect only consumer MS accounts to login, you can specify the authorize URL as:
https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize
First, for the error massage in your question, you need to add the live account into your directory first and then try to use Azure AD v2 endpoint to authenticate. You can not sign in the app with the external account which was not in that directory.
I assume that you want any Microsoft live account can use your app.
Based on this requirement, I suggest you can use Azure AD B2C to achieve this. Azure AD B2C can enables your application to authenticate with any Microsoft account. You can add Microsoft Account as a social identity providers. So that any live accounts can sign up and sign in your App through Azure AD B2C.
You can see more details about Providing sign-up and sign-in to consumers with Microsoft accounts in this official document.
Hope this helps.

On-Behalf-Of Azure Mobile backend - MS Graph

Another attempt to ask a different question surrounding my month long problem:
I'm now trying to initiate the "On-Behalf-Of" flow to get a MS Graph token when users login with a Microsoft Account. As documented here:
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-on-behalf-of
On the client, users log in with a server-flow:
var user = await MobileService.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
On the .NET backend, I am trying to retrieve the MS Graph token:
string clientId = "id-shown-in-app-registration-portal";
string clientSecret = "secret-shown-in-app-registration-portal";
IEnumerable<string> msIdTokenOut = null;
Request.Headers.TryGetValues("x-ms-token-microsoftaccount-access-token", out msIdTokenOut);
string msIdToken = msIdTokenOut.FirstOrDefault();
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/common/oauth2/v2.0");
UserAssertion assertion = new UserAssertion(msIdToken);
ClientCredential cred = new ClientCredential(clientId, clientSecret);
AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", cred, assertion);
I get the following error:
aadsts50027: invalid jwt token. token format not valid.
I've tried every possible combination, from using server-flow to login, using MSAL for client-flow (which doesn't authenticate against App Services with the retrieved token). This has been driving me crazy for over a month. I can't believe how many hoops I have jumped through to get 2 Microsoft products working together. If anyone can steer me towards a solution I would be beyond grateful.
Here is a workaround, I suggest you could enable the mobile server custom authentication by using MSAL returned access token.
More details, you could refer to below steps:
Firstly, you could create a login page which will use MSAL login with the microsoft account. It will return the access token.
Then you could send the request with the access token to the mobile service backend to ask for authentication.
Notice: The logic in the backend which used to check the access token is right, you need achieve by yourself. You could decode the access jwt token to get the aud value. If this value is as same as the client id that means the user have the permission to access mobile backend data.
Then you could use jwt token to get the user information from graph api. After get the user information, you could set the user information value to claims to generate the auth token(using this method AppServiceLoginHandler.CreateToken[Add Microsoft.Azure.Mobile.Server.Login NuGet package]). By using this token the mobile client user could access the mobile backend.
The access token like this:
More details, you could refer to this article to know how to enable custom auth in mobile backend.

Outlook REST API: trying to call API using AZURE AD authentication

Using the office 365 Outlook REST API (version 2), I have a web application managing outlook subscriptions to specific mail boxes. I've been able to use the examples to obtain a token and call the API using the authorization code flow, successfully.
But now, I want to use a client credential flow and get a token using Azure AD authentication via delegate permissions (I gave the application all possible delegate permissions under office 365 exchange online). Similar to what I've seen here: Get Office 365 API access token without user interaction
I've registered my application and gotten my tenant ID, client ID & secret. I've been able to get a token but when I try to use it, I get 401, unauthorized back.
Here's how I'm getting the token:
AuthenticationContext authContext = new AuthenticationContext($"{authority}{tenantId}");
clientCredential = new ClientCredential(client_Id, secret);
authResult = await authContext.AcquireTokenAsync(resource, clientCredential);
authResult.AccessToken;
And here's how I'm trying to use the API (trying to delete the subscription using REST sharp in this code):
var token = await GetOtherToken(account);
rc = new RestClient("https://outlook.office.com/api/v2.0");
rc.AddDefaultHeader("Authorization", $"Bearer {token}");
request = new RestRequest($"me/subscriptions('{restSubId}')", Method.DELETE);
request.AddHeader("Content-Length", "0");
request.AddHeader("Content-Type", "multipart/form-data");
Looks like this is not possible. Please, someone, drop some knowledge. Thanks for reading.
When using client credential flow to acquire a token for resource , you are using application identity instead of as a user's identity. So you should assign application permission for your app(not delegate permissions) . In addition , since you are using app identity instead of user's identity , api can't recognize me(https://outlook.office.com/api/v2.0/me) . Please click here for how to build service and daemon apps in Office 365 .

Categories