Reputation: 35
I am looking for a solution without interactive login, but all the solutions I've found so far have it. Could someone point out how to get an access token for an MFA enabled account without using the interactive approach?
Here is my code:
string clientId = "CLIENTID";
string tenantID = "TENANTID";
string authority = $"https://login.microsoftonline.com/{tenantID}";
string[] scopes = new string[] { "https://outlook.office.com/EWS.AccessAsUser.All" };
string username ="USERNAME";
string password = "PASSWORD";
Microsoft.Identity.Client.IPublicClientApplication app;
app = Microsoft.Identity.Client.PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(authority)
.Build();
var securePassword = new SecureString();
Dictionary<string, string> mfa = new Dictionary<string, string>();
mfa.Add("amr_values", "mfa");
foreach (char c in password) // you should fetch the password keystroke
securePassword.AppendChar(c); // by keystroke
var result = app.AcquireTokenByUsernamePassword(scopes,
username, securePassword)
.WithExtraQueryParameters(mfa)
.ExecuteAsync().Result;
I get this error:
MsalUiRequiredException: 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 '00000002-0000-0ff1-ce00-000000000000'.
And here is the log on Azure AD:
User did not pass the MFA challenge (non interactive).
Upvotes: 1
Views: 1371
Reputation: 5549
If MFA was enabled for a user, then you cannot get token directly with OAuth 2.0 Resource Owner Password Credentials.
But, there is a optional workaround. You can get a new token with refresh token as: Refresh the access token
In this way, you can get new token without any interaction. I see you are willing to use password in your application, so storing and retrieving a refresh should be fine for you.
Note: As refresh token could be used to acquire a new token, so you need to keep the refresh token at a safe place.
Upvotes: 1