title: .NET Core 3.1 to .NET 5 migration - Microsoft Identity Web Platform stopped working
body: <p>With NET 5 officially released, this evening I've migrated from Net Core 3.1 to NET 5, all seemed to go smoothly until I tried to run the app and now find a couple of squiggly lines under two items in the startup.cs that are associated with Microsoft Identity Web platform. This is obviously an instant fail! I wont be able to fire up the app or login to Azure AD until I have this fixed.</p>
  <p>After modifying the csproj file to NET5, I then went to nuget manager and updated all the packages.</p>
  <p>I've absolutely no idea where to start on this issue :(</p>
  <p>Screenshot of the startup.cs file with the squiggles:</p>
  <p><a href="https://i.stack.imgur.com/NmAB9.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/NmAB9.jpg" alt="startup.cs file" /></a></p>
  <p>csproj file:</p>
  <p><a href="https://i.stack.imgur.com/bdVsr.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bdVsr.jpg" alt="enter image description here" /></a></p>
  <p>Nuget Manager with updated packages:</p>
  <p><a href="https://i.stack.imgur.com/fSWul.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fSWul.jpg" alt="enter image description here" /></a></p>
  <p>I notice that the package references at the top of the startup.cs file for MS Identity Web are now greyed out since the migration:</p>
  <p><a href="https://i.stack.imgur.com/szXfy.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/szXfy.jpg" alt="enter image description here" /></a></p>
  <p>Code from the startup.cs file:</p>
  <pre><code>public class Startup
  {
      public Startup(IConfiguration configuration)
      {
          Configuration = configuration;
      }
  
      public IConfiguration Configuration { get; }
  
      public TokenValidatedContext Context { get; set; }
  
      // This method gets called by the runtime. Use this method to add services to the container.
      public void ConfigureServices(IServiceCollection services)
      {
          // Added to original .net core template.
          // ASP.NET Core apps access the HttpContext through the IHttpContextAccessor interface and 
          // its default implementation HttpContextAccessor. It's only necessary to use IHttpContextAccessor 
          // when you need access to the HttpContext inside a service.
          // Example usage - we're using this to retrieve the details of the currrently logged in user in page model actions.
          services.AddHttpContextAccessor();
  
          // DO NOT DELETE (for now...)
          // This 'Microsoft.AspNetCore.Authentication.AzureAD.UI' library was originally used for Azure Ad authentication 
          // before we implemented the newer Microsoft.Identity.Web and Microsoft.Identity.Web.UI NuGet packages. 
          // Note after implememting the newer library for authetication, we had to modify the _LoginPartial.cshtml file.
          //services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
          //    .AddAzureAD(options =&gt; Configuration.Bind(&quot;AzureAd&quot;, options));
  
          ///////////////////////////////////
  
          // Add services required for using options.
          // e.g used for calling Graph Api from WebOptions class, from config file.
          services.AddOptions();
  
          // Sign-in users with the Microsoft identity platform
          services.AddSignIn(Configuration);
  
          // Token acquisition service based on MSAL.NET
          // and chosen token cache implementation
          services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { GraphScopes.UserRead })
              .AddInMemoryTokenCaches();
  
          // Add the MS Graph SDK Client as a service for Dependancy Injection.
          services.AddGraphService(Configuration);
  
          // Create a new instance of the class that stores the methods called
          // by OpenIdConnectEvents(); i.e. when a user logs in or out the app.
          // See section below :- 'services.Configure'
          OpenIdEvents openIdEvents = new OpenIdEvents();
  
          // The following lines code instruct the asp.net core middleware to use the data in the &quot;roles&quot; claim in the Authorize attribute and User.IsInrole()
          // See https://docs.microsoft.com/aspnet/core/security/authorization/roles?view=aspnetcore-2.2 for more info.
          
          services.Configure&lt;OpenIdConnectOptions&gt;(OpenIdConnectDefaults.AuthenticationScheme, options =&gt;
          {
              // The claim in the Jwt token where App roles are available.
              options.TokenValidationParameters.RoleClaimType = &quot;roles&quot;;
              // Advanced config - capturing user events. See OpenIdEvents class.
              options.Events ??= new OpenIdConnectEvents();
              options.Events.OnTokenValidated += openIdEvents.OnTokenValidatedFunc;
              // This is event is fired when the user is redirected to the MS Signout Page (before they've physically signed out)
              options.Events.OnRedirectToIdentityProviderForSignOut += openIdEvents.OnRedirectToIdentityProviderForSignOutFunc;
              // DO NOT DELETE - May use in the future.
              // OnSignedOutCallbackRedirect doesn't produce any user claims to read from for the user after they have signed out.
              options.Events.OnSignedOutCallbackRedirect += openIdEvents.OnSignedOutCallbackRedirectFunc;
          });
  
          // Adding authorization policies that enforce authorization using Azure AD roles. Polices defined in seperate classes.
          services.AddAuthorization(options =&gt;
          {
              // This line may not work for razor at all, havent tried it but what was used in MVC from the MS Project example. Dont delete just yet...
              //options.AddPolicy(AuthorizationPolicies.AssignmentToUserReaderRoleRequired, policy =&gt; policy.RequireRole(AppRole.UserReaders));
  
              // NOTE BELOW - I had to change the syntax from RequireRole to RequireClaim
              options.AddPolicy(AuthorizationPolicies.AssignmentToEditRolesRoleRequired, policy =&gt; policy.RequireClaim(ClaimTypes.Role, AppRole.EditRoles));
              options.AddPolicy(AuthorizationPolicies.AssignmentToViewLogsRoleRequired, policy =&gt; policy.RequireClaim(ClaimTypes.Role, AppRole.ViewLogs));
              options.AddPolicy(AuthorizationPolicies.AssignmentToViewUsersRoleRequired, policy =&gt; policy.RequireClaim(ClaimTypes.Role, AppRole.ViewUsers));
              options.AddPolicy(AuthorizationPolicies.AssignmentToCreateUsersRoleRequired, policy =&gt; policy.RequireClaim(ClaimTypes.Role, AppRole.CreateUsers));
              options.AddPolicy(AuthorizationPolicies.AssignmentToEditUsersRoleRequired, policy =&gt; policy.RequireClaim(ClaimTypes.Role, AppRole.EditUsers));
              options.AddPolicy(AuthorizationPolicies.AssignmentToDeleteUsersRoleRequired, policy =&gt; policy.RequireClaim(ClaimTypes.Role, AppRole.DeleteUsers));
          });
  
          services.AddRazorPages().AddMvcOptions(options =&gt;
          {
              var policy = new AuthorizationPolicyBuilder()
                  .RequireAuthenticatedUser()
                  .Build();
              options.Filters.Add(new AuthorizeFilter(policy));
          }).AddMicrosoftIdentityUI();
  
          // Add the HttpClient factory into our dependancy injection system.
          // That way we can access it at any point.
          // Used for consuming REST Api throughout the Webb App.
          services.AddHttpClient();
          // Adds the service for creating the Jwt Token used for calling microservices.
          // Note we are using our independant bearer token issuer service here, NOT Azure AD
          services.AddScoped&lt;JwtService&gt;();
          // Add service for HttpContext Current User Repository.
          // Used fir fetching properties of the currently logged in user for logging.
          services.AddScoped&lt;ICurrentUser, CurrentUser&gt;();
  
          // The AddAntiforgery() method configures anti-forgery service to pick the anti-forgery 
          // token from request headers rather than request body. This is required because we will 
          // be issuing Ajax requests to the razor page and there won't be any full page post-backs.
          services.AddAntiforgery(options =&gt; options.HeaderName = &quot;MY-XSRF-TOKEN&quot;);
      }
  </code></pre>
  <p>I just don't know how to troubleshoot this...</p>