Using Blazor Server Template with MicrosoftGraph

I am trying to modify the Blazor Server template to work with the Microsoft Graph provider and running into problems. I have updated the app settings with my proper config values and can visit the localhost:5001/admin-ui page and login and see my account information displayed on the page. However when I visit the main page it doesn’t see me as logged in.

This is different behavior from the WASM template as when I do the same workflow, I see my account information on the main page. Any ideas?

I’ve noticed issues with trying to use the same Auth Strategy as Blazor WASM where the Auth State would often get out of sync with the scoped authenticated HttpClient that authenticated the user, it would use a different Auth session to the Browser’s Auth session and would sporadically get lost in time, likely when the server rendering circuit is broken/lost.

The only reliable strategy I’ve found was to take over handling HttpClient cookies and populating it with the Host’s HttpContext cookies when making API requests and writing to the Browser cookies at Authentication where it now survives Circuit losses & App restarts (when using stateless JWT cookies) and stays in sync with the Browser session so you could Authenticate in API Explorer /ui or /locode and it will be authenticated in your Blazor server App & vice versa.

I’ve updated the blazor-server project template to utilize this strategy which requires the latest v6.4.1+ on MyGet.

Wow, thanks for looking into this. I downloaded the new template, cleared my nuget cache and tested the new packages. I can now see my name in the top right corner however I still can’t access any of the secure parts of the site. I have all the roles setup assigned to my account: admin, manager, and employee which I see in admin-ui. Here is the error message:

RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (Employee|Admin)

I can see my roles being populated in the UserAuthRole table but notice in BlazorServerUtils on line 129 that my roles are empty when I debug the code.

Your discover also explains why when I use the ApiSync from the BlazorComponentBase the userauth information is null. However when I use the following:

    var request = HttpContextAccessor?.HttpContext.ToRequest();
    Gateway = new InProcessServiceGateway(request);

Then do Gateway.ApiSync(....) 

My userauth information is available to ormlite.

Are you using JWT cookies? (configured by default) if so can you check if they contain the roles using either the Request Logging Admin UI or https://jwt.io

I’ve also added a /profile page to the blazor-server template which will display the roles of currently authenticated user.

JWT cookies is enabled but I do not see the roles, however something is coming through because I see my roles created in the userauthdetails.

Do not see the roles in the JWT Cookie and the /profile page? Can you try clearing out your cookies and trying again.

Sorry, could have been more clear. I went to the site above after clearing cookies and did not see roles in my JWT cookie. Also, I get a 404 Not Found error for /profile.

/profile is a new page added to the blazor-server template, which also requires updating to latest v6.4.1 on MyGet.

I did that and it doesn’t work, I cleared all nuget caches, cleaned my solution and rebuilt. This caused an issue with BlazorServerAuthenticationStateProvider because it went from having 5 parameters in the base class to 2.

That indicates you’re not using the latest MyGet as this shows it’s working with the latest MyGet:

https://blazor-server.jamstacks.net/profile

Which is automatically deployed from the blazor-server project template repo.

Ok, I will get that resolved. As for JWT Provider, is that required in order for Blazor Server authentication to work properly?

I have encountered an issue where if I add the JWTProvider, I can’t find my access token in the session. I have code that gets the token from authSession.GetAuthTokens(); to build a GraphServiceClient that works only if I comment out the provider.

It should would work for standard cookie / session auth as well but JWT will be more reliable which will be able to survive circuit/app restarts and redeployments without a distributed caching provider.

I’m flying blind without being able to repro anything or seeing any code, as you’re trying to use Microsoft Graph Roles do you have DistinctTableRoles configured?

Are you storing the access tokens in the JWT? Anything beyond essential info needs to be explicitly included. Otherwise you’ll need to fetch it from UserAuthDetails when you need it.

I downloaded the template from the gallery page and every worked as you stated. The profile page worked but shows no roles. I assume that is because the access token provided by msft doesn’t have any roles in it? The id_token seems to be where everything is stored. I will review the application setup to see if I can add that information.

Do you have DistinctTableRoles configured?

Correct. I also notice with Blazor Server that the session only works with I assign the OrmCacheClient to sqlite or in memory. If I assign it to my Sql Server 2019 database after login pages will not render.

Did you resolve the issue with the SQL Server memory optimized tables? Latest MyGet no longer uses a large Text column for the key, but the table would need to be re-created.

Yes, with my fresh Blazor Server template downloaded from the gallery the optimized table cache worked fine.

So when I use the JWTAuthProvider, all my roles are never populate to the cookie and the access tokens can’t be recovered from the session when using authSession.GetAuthTokens();. However when I set UseTokenCookie to false, everything works again.