Redirecting on Access Denied fails

Michael Mastro II 56 Reputation points
2022-02-11T03:09:41.237+00:00

I am running into an issue with redirecting of pages, specifically Access Denied at this moment, though this might also apply to Logout. I am running multiple applications, though only one of them is using Identity, so my Access Denied page is on that app. I am trying to point other applications to that access denied page. This may be an issue once up in QA, Staging, and Production as the application that handles Identity will be the root (www.mydomain.com) and the other apps virtual (www.mydomain.com/app1, www.mydomain.com/app2, etc.) as I have not had it redirect from the virtual apps yet. Though in development it is definitely a problem.
Here is what I am seeing in the log:

Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Debug: AuthenticationScheme: OpenIddict.Server.AspNetCore was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: OpenIddict.Server.AspNetCore was forbidden.
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 353.1054ms 302 
Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer: Debug: Connection ID "18374686485577203859" disconnecting.
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 GET https://localhost:44344/lotro/Account/AccessDenied?ReturnUrl=%2Flotro%2FMenu%2FMenu  
Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware: Trace: All hosts are allowed.
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware: Debug: The request path /Account/AccessDenied does not match a supported file type
Microsoft.AspNetCore.Routing.Matching.DfaMatcher: Debug: No candidates found for the request path '/Account/AccessDenied'
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware: Debug: Request did not match any endpoints

You can see that the Access Denied redirect is looking at the application it is called in. Though in the application in the startup class I have event trigger that are supposed to redirect on access denied to the application that has Identity and the AccessDenied page.

services.AddAuthentication(options =>
            {
                options.DefaultScheme = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme;
            })
                .AddCookie("OpenIddict.Server.AspNetCore", options =>
                {
                    options.ClaimsIssuer = "https://localhost:44318";

                    options.Cookie.Path = "/";
                    options.Events = new CookieAuthenticationEvents()
                    {
                        OnRedirectToAccessDenied = (context) =>
                        {
                            context.HttpContext.Response.Redirect("https://localhost:44309/Identity/Account/AccessDenied");
                            return Task.CompletedTask;
                        }
                    };
                    options.Events = new CookieAuthenticationEvents()
                    {
                        OnRedirectToLogout = (context) =>
                        {
                            context.HttpContext.Response.Redirect("https://localhost:44309/Identity/Account/Logout");
                            return Task.CompletedTask;
                        }
                    };
                })
                .AddOpenIdConnect(options =>
                {
                    options.ClientId = Configuration.GetSection("openId:ClientId").Value;
                    options.ClientSecret = Configuration.GetSection("openId:ClientSecret").Value;

                    options.RequireHttpsMetadata = true;
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.SaveTokens = true;

                    options.ResponseType = OpenIdConnectResponseType.Code;
                    options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;

                    options.Authority = new Uri(Configuration.GetSection("BaseAddresses:Api").Value).ToString();

                    options.SecurityTokenValidator = new JwtSecurityTokenHandler
                    {
                        InboundClaimTypeMap = new Dictionary<string, string>()
                    };

                    options.TokenValidationParameters.NameClaimType = "name";
                    options.TokenValidationParameters.RoleClaimType = "role";
                });

How do I get the redirect to actually go to where I would like it to go?

Developer technologies | ASP.NET | ASP.NET Core
{count} vote

1 answer

Sort by: Most helpful
  1. Michael Mastro II 56 Reputation points
    2022-02-14T16:37:36.027+00:00

    Triggers in the cookie were not going to work I guess. I set the triggers on the CookieDefaults. Works now.

    services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.Events.OnRedirectToAccessDenied = new Func<Microsoft.AspNetCore.Authentication.RedirectContext<CookieAuthenticationOptions>, Task>(context =>
                    {
                        context.Response.Redirect(Configuration.GetSection("BaseAddresses:IdentityRazorPages").Value + "Identity/Account/AccessDenied");
                        return context.Response.CompleteAsync();
                    });
    
                    options.Events.OnRedirectToLogout = new Func<Microsoft.AspNetCore.Authentication.RedirectContext<CookieAuthenticationOptions>, Task>(context =>
                    {
                        context.Response.Redirect(Configuration.GetSection("BaseAddresses:IdentityRazorPages").Value + "Identity/Account/Logout");
                        return context.Response.CompleteAsync();
                    });
                });
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.