Reputation: 93
We have recently implemented some conditional access policies that require multi-factor authentication for certain applications. One of those policies forces CA on some datasets that are also exposed through Graph, so specific Graph scopes now require multi-factor authentication.
I'm struggling with how to handle this scenario in a .Net web app using the MSAL v3 preview library. My web app itself does not fall under the CA policy, but it's attempting to request a graph scope that does.
When configuring authentication, I'm passing all the graph scopes that are required by the application:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ClientId,
Authority = Authority,
RedirectUri = RedirectUri,
Scope = "openid profile offline_access " + GraphScopes,
PostLogoutRedirectUri = postLogoutRedirectUri,
That authentication flow does not force the user to MFA. The next step is the AuthorizationCodeReceived event. In there I'm creating a token cache and attempting to obtain a token via the authorization code:
var code = context.Code;
string signedInUserId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserId, context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase). GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(AppKey), userTokenCache, null);
string[] scopes = GraphScopes.Split(new char[] { ' ' });
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, scopes);
The AcquireTokenByAuthorizationCodeAsync method is the one that throws an exception - MsalUiRequiredException. The exception includes claims that I'm assuming need to somehow be used to force MFA.
That's where I've hit a roadblock. What do I do with those claims? I've seen some documentation indicating that I should use them as extraQueryParameters when requesting a token, but I have yet to find a method that would allow me to do that. I found a method on the ConfidentialClientApplicationBuilder class that allows me to specify claims, but I still receive MsalUiRequiredException.
For now my solution has been to add my web app to the original Conditional Access policy. That forces MFA on the front-end of the auth flow and satisfies Graph. To me that seems like an unnecessary step. I should be able to handle the error in my web app and force the MFA programmatically.
Upvotes: 4
Views: 3951
Reputation: 1517
There seems to be a dedicated page in MSAL GitHub that addresses this issue. The below snapshot shows the relevant section from the documentation.
Essentially, all we need is a way to specify the required claims in extraQueryParameters. In your delegate for AuthorizationCodeReceived
, you can use ConfidentialClientApplication to achieve the desired outcome. In particular, the GetAuthorizationRequestUrlAsync method of ConfidentialClientApplication
allows the creation of custom URI to the authorize endpoint with the required claims in extra query parameters. Redirecting the user to the above endpoint would enforce MFA and lead to successful access token generation. Here is a link to a GitHub sample that uses GetAuthorizationRequestUrlAsync
method to specify custom claims in extra query parameters.
Upvotes: 2