Infinite loop between CMS and Okta

I am having trouble setting up Okta with Episerver (ASP.NET).

Here a description of my issue.

I start by going to http://localhost:58597/ - This page requires authentication, so I am sent to the Okta login page and after logging in, I am returned to http://localhost:58597/
So far so good. I now go to http://localhost:58597/episerver - which I don’t have access to and this starts an infinite loop between Episerver and Okta.

Here’s some info from my network tab in Chrome.

GET  http://localhost:58597/episerver                            302 Found (Location:
GET 200 OK
POST http://localhost:58597/authorization-code/callback          302 Found (Location: http://localhost:58597/episerver)

… and then it starts over

I would rather have the user sent to a static “you do not have access” page than back to Okta.
How on earth do I do that?

Here is my Startup.cs class

using EPiServer.Cms.UI.AspNetIdentity;
using EPiServer.ServiceLocation;
using HYG.Com.Logic.Authorization.Helpers;
using HYG.Com.Logic.Authorization.Models;
using HYG.Com.Logic.Authorization.Services;
using HYG.Com.Logic.Constants;
using Microsoft.Owin;
using Microsoft.Owin.Extensions;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Okta.AspNet;
using Owin;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web.Helpers;

[assembly: OwinStartup(typeof(HYG.Com.Web.Startup))]

namespace HYG.Com.Web
	public class Startup
		public void Configuration(IAppBuilder app)
			// Instantiate the Okta options using the settings from the web.config.
			OktaMvcOptions oktaMvcOptions = new OktaMvcOptions
			OktaDomain = ConfigurationManager.AppSettings["okta:OktaDomain"],
			ClientId = ConfigurationManager.AppSettings["okta:ClientId"],
			ClientSecret = ConfigurationManager.AppSettings["okta:ClientSecret"],
			RedirectUri = ConfigurationManager.AppSettings["okta:RedirectUri"],
			PostLogoutRedirectUri = ConfigurationManager.AppSettings["okta:PostLogoutRedirectUri"],
			GetClaimsFromUserInfoEndpoint = true,
			Scope = new List<string> { "openid", "profile", "email" }

		// Configure the OWIN cookie authentication middleware.
		CookieAuthenticationOptions cookieAuthenticationOptions = new CookieAuthenticationOptions
			LoginPath = new PathString("/account/login"),

		// Register the OWIN middleware components.

		// Remap logout.
		app.Map("/util/logout.aspx", map =>
			map.Run(ctx =>
				// Log out the user.
				ctx.Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType, OktaDefaults.MvcAuthenticationType);
				return Task.FromResult(0);

		// Map some of the claims from Okta to Microsoft's schemas in order for Episerver to pick up on them.
		app.Use((context, next) =>
			if (context.Authentication.User.Identity is ClaimsIdentity claimsIdentity && claimsIdentity.IsAuthenticated)
				// Add name claim as
				var name = claimsIdentity.Claims.Where(claim => claim.Type == "name").Select(claim => claim.Value).FirstOrDefault() ??
						   claimsIdentity.Claims.Where(claim => claim.Type == "preferred_username").Select(claim => claim.Value).FirstOrDefault();

				claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, name));

				// Add all group claims for the user as
				IEnumerable<Claim> groups = claimsIdentity.Claims.Where(claim => claim.Type == "groups");

				foreach (var group in groups)
					claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, group.Value));

			return next.Invoke();


		AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;