Azure AD Silent Authentication from Desktop App C# - c#

I am trying to have silent authentication with Azure AD from a desktop app. I am using MSAL.NET 4.72.2, specifically this particular call. It is not recommended by Microsoft for some specific reasons, none of them applies to my case. However, it is supposed to work silently, like in a traditional case, you pop up a login WinForm in the app and provide user name and password. Then click OK and eventually it comes down to this call:
authResult = await app.AcquireTokenByUsernamePassword(
scopes,
ClientApp.SafeStorage.DecryptString(ClientApp.Username),
ClientApp.SafeStorage.DecryptString(ClientApp.Pwd))
.ExecuteAsync(CancellationToken.None)
.ConfigureAwait(true);
where ClientApp.Username and ClientApp.Pwd are username and password.
The problem is that this call fails against Azure AD without MFA enabled for that account:
Microsoft.Identity.Client.MsalServiceException: 'A configuration issue is preventing authentication - check the error message from the server for details. You can modify the configuration in the application registration portal. See https://aka.ms/msal-net-invalid-client for details. Original exception: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
Trace ID: 50d49e42-d5e4-4cd8-984d-540c3d538a00
Correlation ID: 7874e878-1084-4f32-9679-69030a2dbed8
Timestamp: 2022-11-02 23:09:46Z'

You need to enable Public Client Flows on your app registration. As below:

Related

Accessing Guest outlook.office365.com mailbox via IMAP- Authenticate Failed Error

I have followed all steps to use client credentials grant flow to authenticate IMAP.
Registered my app on Azure AD (multitenant)
Set App permissions (Screenshot attached)
Set Service Principals
Acquiring token with scope- "https://outlook.office365.com/.default" and doing post- https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token
I do get the token but it throws "NO AUTHENTICATE FAILED" error.
Here's the issue- The app was created and permissions set using TESTDOMAIN1 account. So it works/authenticates without any problems for emails with abc#TESTDOMAIN1.com.
But if I try to access a guest account(account added in Azure using invitation) like xyz#TESTDOMAIN2.com, it generates the token but throws NO AUTHENTICATE FAILED error.
I tried updating the service principal as well to access this emailbox but I got error there too. (Screenshot attached)
Please suggest if I'm missing something here. All I want to do is access any of my users (Azure AD Users or external users) to access my app and be able to use the api and give access to mailbox.
ApiPermissions
GuestAccount
ServicePrincipalError
I tried to reproduce the same in my environment and got the below results:
I created an Azure AD application and added permission like below:
I generated the authorization code with below parameters.
GET
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=e626f30a-80ea-4530-81e9-ebxxxxx
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=https://graph.microsoft.com/IMAP.AccessAsUser.All offline_access
&state=12345
I generated access token successfully like below.
https://login.microsoftonline.com/common/oauth2/v2.0/token
grant_type:authorization_code
client_id:e626f30a-80ea-4530-81e9-ebxxxxx
client_secret:client_secret
scope://graph.microsoft.com/IMAP.AccessAsUser.All offline_access
redirect_uri:https://jwt.ms
code:code

How to call Azure AD B2C edit profile user flow from blazor app?

When I am trying to run user flow manually from portal.azure.com by clicking 'Run user flow' at the bottom I can select the application and reply URL.
I have defined two reply URLs:
https://localhost:5001/signin-oidc
https://jwt.ms
I select the first reply URL and below that information the 'Run user flow endpoint' is generated automatically. When I copy this endpoint and try to call from my blazor app it is working correctly. I can log in and change my profile info. Then, I can click continue to reply to my blazor app.
After clicking I want to get back to my app but I have an error:
Error.
An error occurred while processing your request.
Request ID:
00-f13479803a4cdeb7d3e203f0910e3688-a0619e9d48caf391-00
Details OpenIdConnectAuthenticationHandler: message.State is null or
empty.
When I set the reply URL to jwt.ms everything works fine.
How to call Edit Profile User Flow from the blazor app properly?
There are below few workaround may help to achieve the above requirement
Kindly check the signuporsignin.xml b2c userflow policy for correct tenant id and public policy uri in that policy file specifically check the technical profile id and inherent output claims regarding post successful authentication with Azure ad b2c .
Since after successful authentication to the blazor app you are able to login and able to change the profile info in the signinsignup user flow page successfully ,But when returning to the blazor client application you are encountering an error that displays the State parameter is null or empty, which inherently implies that the token access authentication is not passed on or the token has is broken/missing or misinterpreted during the changes of pages.
Thus i would suggest you to please check the program.cs file in the blazor client application code whether it includes the below code snippets or not.
builder.Services.AddMsalAuthentication(options => { builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); options.ProviderOptions.DefaultAccessTokenScopes.Add("api://https://domain.onmicrosoft.com/cxxxx-1xx-4xxxe-aad0-4xxxxx/API.Access"); });
The above code snippet states that the blazor client application has exposed his api to the blazor server application as a provider.
Further also please check the authentication.razor file for the parameter to be passed on public string
Once the above has been checked and found correct then please ensure that the appsettings.json file on both the client & server applications has the correct respective client Id and the policy name mentioned. Also check the Azure ADb2c app registration for the details in blazor web assembly application.
For more information please refer the below links:-
Secure an ASP.NET Core Blazor WebAssembly hosted app with Azure Active Directory | MICROSOFT DOCUMENTATION

How to diagnose Microsoft Identity authentication failure?

I have an ASP.NET Core 3.1 web API application that is protected by Azure Authentication. I also have an Angular 11 application that calls the web API.
They work fine on our integration environment. But authentication fails on the test environment.
The Angular app authenticates fine using msal-angular library, it gets the access token and includes it when calling the web API. But the web API fails to retrieve the identity from the bearer token.
After deleting and recreating both (frontend and backend) Azure APP registrations several times and after reconfiguring them, the authentication still fails. I don't know what is the cause, so this is why I need to diagnose it.
I have enabled JwtBearerMiddlewareDiagnosticsEvents and I can see 'Begin OnAuthenticationFailedAsync' and 'End OnAuthenticationFailedAsync' on the logs. But it isn't enough information. It tells you no more that the events are raised, no additional information.
I've read the following article on documentation that tells you how to configure logging in MSAL.NET, but I don't think it's applicable to web API.
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-logging-dotnet
So the question is: How can I figure out why the authentication is failing? Is there any way to log the cause?
UPDATE:
I'm closer, I set log level to trace and now I see the following on the log of asp.net core web api app:
IDX10511: Signature validation failed. Keys tried: '[PII is hidden.
For more details, see https://aka.ms/IdentityModel/PII.]'. \nkid:
'[PII is hidden. For more details, see
https://aka.ms/IdentityModel/PII.]
UPDATE:
I get the following error:
Bearer was not authenticated. Failure message: IDX10214: Audience
validation failed. Audiences: '242e8f40-d795-43bc-8ac8-8eed3df71745'.
Did not match: validationParameters.ValidAudience:
'b99e89fc-8a1c-4605-8c18-796d7064037e' or
validationParameters.ValidAudiences: 'null'.
'242e8f40-d795-43bc-8ac8-8eed3df71745' is the AppId on the web api app registration manifest.
'b99e89fc-8a1c-4605-8c18-796d7064037e' is the client id of the web api registration.
The scope is 'api://242e8f40-d795-43bc-8ac8-8eed3df71745/api-access'.
This is how I set the scope:
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set('https://api.example.com/*', ['api://242e8f40-d795-43bc-8ac8-8eed3df71745/api-access']);
return {
interactionType: InteractionType.Popup,
protectedResourceMap
};
}
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Popup,
authRequest: {
scopes: ['api://242e8f40-d795-43bc-8ac8-8eed3df71745/api-access']
},
loginFailedRoute: '/login-failed'
};
}
Your problem has been solved. The problem is that the configuration of the web api is wrong. You need to create them again and reconfigure .
According to my experience, you need to create two applications in Azure, one representing the web api application and the other representing the client application (ie Angular 11 application).
Then you need to expose the api of the web api application in Azure and add the Angular 11 application as a client application to the web api application.
Finally, when requesting an access token, you need to set the scope to: api://{web api client id}/{scope name}.

Can't sign in with corporate account when acquiring authentication token with PublicClientApplication

I have a custom UWP application which I have registered in portal.azure.com. The app has been configured to support all account types ("Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)").
In my application I create a IPublicClientApplication like so:
PublicClientApp = PublicClientApplicationBuilder.Create(appId)
.WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount)
.WithLogging((level, message, containsPii) =>
{
ConfigurationHandler.Log.Info($"MSAL: {level} {message} ");
}, LogLevel.Warning, enablePiiLogging: false, enableDefaultPlatformLogging: true)
.WithUseCorporateNetwork(true)
.Build();
And later on I'm trying to acquire an authentication token like so:
authResult = await PublicClientApp.AcquireTokenInteractive(Scopes)
.ExecuteAsync()
.ConfigureAwait(false);
This will open the sign in popup window where user enters their email address and password. The authentication works without issues when I'm using a personal (xyz#outlook.com) account but it doesn't work with work accounts. The window is trying to redirect to the organization sign in page after entering the work email and clicking next. The redirect process begins but always ends up to following error:
"We can't connect to the service you need right now. Check your network connection or try this again later"
I have tried to add WithRedirectUri with value "urn:ietf:wg:oauth:2.0:oob" to the PublicClientApplication creation but it didn't help. That's the only redirect URI I have configured in Azure Portal.
Is there some other setting which I'm not aware of? How can I get rid of this error and get the work accounts working as well?
EDIT: I forgot to mention it's a desktop application.
I can not reproduce your issue on my side. My steps seem the same as yours, anyway, here is the screenshot for your reference. Also, here is an complete guide.
By the way, if you want to integrate authentication on federated domains, you need to enale additional capabilities.
1.Open Package.appxmanifest.
2.Select Capabilities and enable the following settings:
Enterprise Authentication
Private Networks (Client & Server)
Shared User Certificates
This issue was resolved by adding a missing certificate to Trusted Root Certification Authorities in Windows certificate manager.

Azure AD: user_interaction_required issue when authenticating a native application

I have Exchange Online from Office 365 with a mailbox and I need to access this mailbox with my console C# application that uses Managed EWS. The requirement is that the console application should use OAuth authentication to access the Exchange Online.
I have Azure AD set up, and created an application there, received clientid and redirect uri. I have given full permissions to the application - please have a look at the screenshot below:
I'm using Active Directory Authentication Library for .NET (latest version from NuGet) to issue a token, but having a problem to get it running...
My code is:
AuthenticationContext authenticationContext = new AuthenticationContext("https://login.windows.net/rsoftgroup.onmicrosoft.com", false);
AuthenticationResult authenticationResult = null;
try
{
var authenticationTask = authenticationContext.AcquireTokenAsync(
"outlook.office365.com",
"c4fa7d60-df1e-4664-a8f8-fb072d0bb287",
new Uri(redirectUri),
new PlatformParameters(PromptBehavior.Never)
);
authenticationTask.Wait();
authenticationResult = authenticationTask.Result;
exchangeService.Credentials = new OAuthCredentials(authenticationResult.AccessToken);
}
catch (AdalException)
{
// Exception occured on the authentication process.
}
I get AdalException with message: "user_interaction_required: One of two conditions was encountered: 1. The PromptBehavior.Never flag was passed, but the constraint could not be honored, because user interaction was required. 2. An error occurred during a silent web authentication that prevented the http authentication flow from completing in a short enough time frame"
Can somebody help me how to solve it?
I need the OAuth authentication to work without user interaction, as this will be a command line application...
Any suggestions highly appreciated.
Your application still needs to authenticate as some user, currently if you look at your code you don't authenticate because of PromptBehavior.Never and you don't specify any user-credentials and use the implicit auth flow eg http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
For a standard Console apps where you are going to authenticate (eg ask for credentials when the app is run) I would use out of band call urn:ietf:wg:oauth:2.0:oob (you then don't need a redirection endpoint) and set your code to prompt eg
AuthenticationContext ac = new AuthenticationContext("https://login.windows.net/Common");
var authenticationTask = ac.AcquireTokenAsync(
"https://graph.windows.net",
"5471030d-f311-4c5d-91ef-74ca885463a7",
new Uri("urn:ietf:wg:oauth:2.0:oob"),
new PlatformParameters(PromptBehavior.Always)
).Result;
Console.WriteLine(authenticationTask.AccessToken);
When you run the Console app windows and the ADAL library will handle the plumbing and show the correct authentication prompts and get the Token back and you get the benefits of reduce attack surface over prompting for the credentials yourself in your code (or as parameters etc)
As Venkat comments suggests if you don't need to use EWS (eg no existing code base investment etc) then using the REST endpoints maybe a better solution if your building a daemon type application as you can take advantage of this type of auth flow eg https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow/

Categories

Resources