Как исправить ошибку 404 при выходе из приложения ASP. NET Core MVC против Azure AD? - PullRequest
0 голосов
/ 28 января 2020

Я интегрирую ASP. NET Core MVC 3.0 приложение в Azure AD для аутентификации и авторизации, и все работает хорошо, но когда я пытаюсь выйти из системы, однажды login.microsoftonline.com выписывает меня , он перенаправляется в мое приложение, и затем появляется следующая ошибка:

No webpage was found for the web address:

https://localhost:5002/Account/SignOut?page=%2FAccount%2FSignedOut

Путь, который я использую для вызова процесса выхода из системы, - /AzureAD/Account/SignOut.

Содержимое appsettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "[OMITTED]",
    "TenantId": "[OMITTED]",
    "ClientId": "[OMITTED]",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Это содержимое моего Startup.cs класса:

using System.Collections.Generic;
using System.Globalization;
using MySite.WebSite.Helpers;
using MySite.WebSite.Models.Validators;
using MySite.WebSite.Models.ViewModels;
using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;

namespace MySite.WebSite
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services
                .AddAuthentication(AzureADDefaults.AuthenticationScheme)
                .AddAzureAD(options => Configuration.Bind("AzureAd", options));

            services.Configure<CookieAuthenticationOptions>(AzureADDefaults.CookieScheme, options =>
            {
                options.AccessDeniedPath = "/Home/AccessDenied";
                options.LogoutPath = "/";
            });

            services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
            {
                options.Authority += "/v2.0/";
                options.TokenValidationParameters.ValidateIssuer = false;
            });

            services.AddLocalization(options => options.ResourcesPath = "Resources");
            services
                .AddControllersWithViews(options => options.Filters.Add(GetAuthorizeFilter()))
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
                .AddDataAnnotationsLocalization()
                .AddFluentValidation();

            services.AddTransient<IValidator<ContactIndexViewModel>, ContactIndexViewModelValidator>();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseRequestLocalization(GetLocalizationOptions());
            app.UseStaticFiles(GetStaticFileOptions());
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

        private RequestLocalizationOptions GetLocalizationOptions()
        {
            var cookie_request_culture_provider = new CookieRequestCultureProvider
            {
                CookieName = "UserCulture"
            };
            var providers = new List<IRequestCultureProvider>()
            {
                cookie_request_culture_provider,
                new AcceptLanguageHeaderRequestCultureProvider()
            };

            var result = new RequestLocalizationOptions
            {
                RequestCultureProviders = providers,
                SupportedCultures = Cultures.SupportedCultures,
                SupportedUICultures = Cultures.SupportedCultures,
                DefaultRequestCulture = new RequestCulture(Cultures.DefaultCulture)
            };
            return result;
        }

        private StaticFileOptions GetStaticFileOptions()
        {
            var result = new StaticFileOptions
            {
                ServeUnknownFileTypes = true,
                DefaultContentType = "text/plain"
            };
            return result;
        }

        private AuthorizeFilter GetAuthorizeFilter()
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            var result = new AuthorizeFilter(policy);
            return result;
        }
    }
}

1 Ответ

1 голос
/ 10 февраля 2020

Оказывается это известная проблема в Microsoft.AspNetCore.Authentication.AzureAD.UI; этот пакет реализует поток аутентификации / авторизации Azure AD в ASP. NET Core, и частью этого является встроенный AccountController (область AzureAD), который снимает с вас процессы входа в систему. Проблема в том, что действие SignOut жестко кодирует перенаправление на /Account/SignOut?page=%2FAccount%2FSignedOut после завершения процесса выхода из системы, и есть проблема.

Мне удалось решить ее, реализовав небольшой AccountController (без области) и добавив одно действие SignOut, которое обрабатывает перенаправление с Microsoft.AspNetCore.Authentication.AzureAD.UI s AccountController:

[AllowAnonymous]
public class AccountController : Controller
{
    [HttpGet]
    public IActionResult SignOut(string page)
    {
        return RedirectToAction("Index", "Home");
    }
}
...