4

I am working on a DotNet Core Razor application that uses OpenIdConnect to authenticate against Azure AD. This site is currently targeting the .net 5.0 framework. I have the Openid connect authentication working for the site. My next goal is to use Microsoft Graph to query Azure AD for the groups that the user belongs to. I downloaded a quickstart and have successfully gotten that to run, also targeting the .net 5.0 framework. The quickstart site will execute the code I have written to get the groups that the user belongs to. When I configure my Razor site to run the same code, I get a null reference exception on the first attempt to use the GraphServiceClient object that is injected into the page. I have compared the Azure AD setup for the quickstart to the setup for the Razor site and cannot see any differences other than different values for ClientId and Client Secret.

Here is the section of code from the startup of the Razor site

string[] initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split('');
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration, "AzureAd", "AzureAD", cookieScheme: null, 
subscribeToOpenIdConnectMiddlewareDiagnosticsEvents: true)
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches(options => { options.AbsoluteExpirationRelativeToNow = 
TimeSpan.FromDays(90); });

which is identical to the code running in the quickstart site.

When I use the GraphServiceClient object injected into the page on the Razor site, with this call

currentUser = await _graphServiceClient.Me.Request().GetAsync();

I get a null reference error. Examining the GraphServiceClient object in the debugger does not reveal anything obvious, I have compared the object injected into the Razor site, which fails, against the object in the Quickstart site, which works, and don't have a clue as to any difference.

This is the Azure Ad section from the appsettings.json file.

"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "qualified.domain.name",
"TenantId": "<My Tenant Id>",
"ClientId": "<My client Id>",
"CallbackPath": "/signin-oidc",
"ClientSecret": "<My client secret>",
"ClientCertificates": [],
// the following is required to handle Continuous Access Evaluation challenges
"ClientCapabilities": [ "cp1" ]
},
"DownstreamApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "User.Read"
},

Here are the settings for API permissions in Azure AD

I can post the stack trace of the error and any other relevant information.

This is the link to the quickstart that I have working:

Here are the details of the exception that happens on the call to the GraphServiceClient object.

Inner exception

IDW10503: Cannot determine the cloud Instance. The provided authentication scheme was ''. Microsoft.Identity.Web inferred 'Identity.Application' as the authentication scheme. Available authentication schemes are 'AzureAD,Identity.Application,Identity.External,Identity.TwoFactorRememberMe,Identity.TwoFactorUserId'.

Stack Trace:

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Graph.HttpProvider.<SendAsync>d__18.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Graph.BaseRequest.<SendRequestAsync>d__40.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Graph.BaseRequest.<SendAsync>d__34`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Graph.UserRequest.<GetAsync>d__5.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at AdminPanel.Areas.Identity.Pages.Account.ExternalLoginModel.<GetSecurityGroups>d__29.MoveNext() 

Bob Ahrens
  • 41
  • 4
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Trevor Apr 25 '22 at 17:55
  • 1
    No, I know what a NullReference exception is. The exception happens in the GraphService client code that I am calling. – Bob Ahrens Apr 26 '22 at 11:38
  • Same Error here. Did you manage to find a solution? – João Pedro Sá Medeiros May 27 '22 at 19:09
  • No, I have not gotten this to work. Here is a really good article that explains the way the authentication stack works in ASP.NET Core. https://stackoverflow.com/questions/52492666/what-is-the-point-of-configuring-defaultscheme-and-defaultchallengescheme-on-asp. I made many changes based on the information in this article, but none of the changes I tried resolved the issue. As a workaround, we wrote a Powershell task that got the same information out of Azure AD and scheduled it to run on a regular basis. I still want to get this to work in our Razor application. – Bob Ahrens May 31 '22 at 12:41
  • I have exactly the same problem. Found the quickstart app and that works, but not in my own app and I cant see a difference. – JohnnyJP Jun 10 '22 at 15:44

1 Answers1

0

I have the same error with a Teams App using Graph authentication code that works perfectly well in a Blazor Server app.

My Blazor startup code looks like this:

    builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
.AddDownstreamWebApi("DownstreamApi",builder.Configuration.GetSection("DownstreamApi"))
     .AddInMemoryTokenCaches();

Graph JSON is:

 "MicrosoftGraph": {
    "Scopes": "user.read",
    "BaseUrl": "https://graph.microsoft.com/v1.0"
  },
ficelles
  • 429
  • 1
  • 4
  • 7