Авторизация происходит до аутентификации после миграции на. net core 3.1 - PullRequest
1 голос
/ 28 марта 2020

После миграции с. net core 2.2 на. net core 3.1 и после некоторого времени, необходимого для исправления всех ошибок в зависимости от документации, после запуска приложения метод авторизации получает доступ до того, как он требует от пользователя быть аутентифицированным.

Я использую OpenId Connect с AD FS для аутентификации и пользовательский метод PermissionGranted для авторизации. И этот метод получает удар, прежде чем он требует аутентификации пользователя.

Это код моего файла Startup.cs:

public class Startup
{
    private readonly ConfigSettings settings;
    private readonly GetSettings configSettings;
    private readonly MyMemoryCache myMemoryCache;

    public Startup(IWebHostEnvironment env, IConfiguration configuration)
    {
        configSettings = new GetSettings();
        settings = configSettings.getSettings();
        Configuration = configuration;
        Environment = env;
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        myMemoryCache = new MyMemoryCache();

        Log.Logger = new LoggerConfiguration().Enrich.FromLogContext()
           .WriteTo.Console()
           .WriteTo.File(settings.LogFile, rollingInterval: RollingInterval.Day)
           .WriteTo.ApplicationInsights(new TelemetryConfiguration(settings.AppInsightsConnection), TelemetryConverter.Events)
           .CreateLogger();
    }

    public IConfiguration Configuration { get; }
    private IWebHostEnvironment Environment { get; }
    public IServiceProvider ServiceProvider { get; set; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(Log.Logger);
        services.AddSingleton(settings);
        services.AddHttpContextAccessor();
        services.AddRouting(options => options.LowercaseUrls = true);

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => false;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = "oidc";
        })
           .AddCookie("Cookies", options =>
           {
               options.AccessDeniedPath = "/users/denied";
           })
           .AddOpenIdConnect("oidc", options =>
           {
               options.SignInScheme = "Cookies";
               options.MetadataAddress = settings.MetadataAddress;
               options.ClientId = settings.ClientId;
               options.GetClaimsFromUserInfoEndpoint = true;
               options.ResponseType = OpenIdConnectResponseType.IdToken;
               options.SignedOutRedirectUri = settings.PostLogoutUri;
               options.SaveTokens = true;
               options.UseTokenLifetime = true;

               options.TokenValidationParameters = new TokenValidationParameters
               {
                   ValidateAudience = true,
                   ValidAudience = settings.ClientId,
                   ValidateIssuer = true,
                   ValidIssuer = settings.Issuer,
                   ValidateLifetime = true,
                   RequireExpirationTime = true
               };

               options.Events = new OpenIdConnectEvents
               {
                   OnRemoteFailure = context =>
                   {
                       context.HandleResponse();
                       context.Response.Redirect("/Login");

                       return Task.FromResult(0);
                   },
                   OnTicketReceived = context =>
                   {
                       // Configuration to make the Authentication cookie persistent for 8 hours (after 8 hours it expires and the user has to re-authenticate)
                       context.Properties.IsPersistent = true;
                       context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(8);

                       return Task.FromResult(0);
                   }
               };

               options.Events.OnRedirectToIdentityProvider = context =>
               {
                   context.ProtocolMessage.Prompt = "login";
                   return Task.CompletedTask;
               };
           });

        Audit.Core.Configuration.Setup()
           .UseSqlServer(config => config
           .ConnectionString(settings.ConnectionString)
           .TableName("AuditEvents")
           .IdColumnName("EventId")
           .JsonColumnName("AuditData")
           .LastUpdatedColumnName("LastUpdatedDate"));

        services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
        services.AddApplicationInsightsTelemetry(settings.AppInsightsConnection);

        services.AddMvc(options =>
        {
            var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

        // Use NewtonsoftJson and custom date format
        services.AddControllers().AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
        });

        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromMinutes(15);
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;  // Make the session cookie essential
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Permissions", policy => policy.RequireAssertion(context => PermissionGranted(context)));
        });

        services.AddDbContext<PasswordManagerContext>(options =>
            options.UseSqlServer(settings.ConnectionString));

        services.AddSingleton<MyMemoryCache>();

        services.AddPaging(options =>
        {
            options.ViewName = "PagerUI";
            options.HtmlIndicatorDown = " <span>&darr;</span>";
            options.HtmlIndicatorUp = " <span>&uarr;</span>";
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSession();
        app.UseCookiePolicy();

        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Login}/{action=Index}/{id?}");

            //endpoints.MapFallbackToController("Index", "Home");
        });
        ServiceProvider = app.ApplicationServices;
    }

Согласно официальным документам, порядок этих :

 app.UseRouting();
 app.UseAuthentication();
 app.UseAuthorization();
 app.UseEndpoints

имеет значение, но в моем коде они упорядочены правильно.

Что может отсутствовать или что может быть не так в конфигурации?

Заранее спасибо

...