19 votes

Aucun authenticationScheme n'a été spécifié et aucun DefaultForbidScheme n'a été trouvé avec l'autorisation basée sur une politique personnalisée.

J'ai un gestionnaire d'autorisation basé sur une politique personnalisée comme défini ci-dessous. L'authentification est gérée avant que l'utilisateur n'accède à l'application, je n'ai donc besoin que de l'autorisation. J'obtiens l'erreur suivante :

Aucun authenticationScheme n'a été spécifié, et il n'y avait pas de DefaultForbidScheme.

Si le contrôle des autorisations réussit, je ne reçois pas d'erreur et tout va bien. Cette erreur ne se produit que lorsque le contrôle des autorisations échoue. Je m'attendrais à ce qu'un code 401 soit renvoyé en cas d'échec.

public class EasRequirement : IAuthorizationRequirement
{
    public EasRequirement(string easBaseAddress, string applicationName, bool bypassAuthorization)
    {
        _client = GetConfiguredClient(easBaseAddress);
        _applicationName = applicationName;
        _bypassAuthorization = bypassAuthorization;
    }

    public async Task<bool> IsAuthorized(ActionContext actionContext)
    {
        ...
    }
}

public class EasHandler : AuthorizationHandler<EasRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, EasRequirement requirement)
    {
        var mvcContext = context.Resource as ActionContext;

        bool isAuthorized;

        try
        {
            isAuthorized = requirement.IsAuthorized(mvcContext).Result;
        }
        catch (Exception)
        {
            // TODO: log the error?
            isAuthorized = false;
        }

        if (isAuthorized)
        {
            context.Succeed(requirement);
            return Task.CompletedTask;
        }

        context.Fail();
        return Task.FromResult(0);
    }
}

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        var easBaseAddress = Configuration.GetSection("EasBaseAddress").Value;
        var applicationName = Configuration.GetSection("ApplicationName").Value;
        var bypassAuthorization = bool.Parse(Configuration.GetSection("BypassEasAuthorization").Value);

        var policy = new AuthorizationPolicyBuilder()
            .AddRequirements(new EasRequirement(easBaseAddress, applicationName, bypassAuthorization))
            .Build();

        services.AddAuthorization(options =>
        {
            options.AddPolicy("EAS", policy);
        });

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddSingleton<IAuthorizationHandler, EasHandler>();
    }

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

        app.UseHttpsRedirection();
        app.UseAuthentication();

        app.UseMvc();
    }
}

22voto

poke Points 64398

L'autorisation et l'authentification sont étroitement liées dans ASP.NET Core. Lorsque l'autorisation échoue, elle sera transmise à un gestionnaire d'authentification pour gérer l'échec de l'autorisation.

Ainsi, même si vous n'avez pas besoin d'une authentification réelle pour identifier vos utilisateurs, vous devrez quand même mettre en place un schéma d'authentification capable de gérer les résultats des interdictions et des défis (403 et 401).

Pour ce faire, vous devez appeler AddAuthentication() et configurer un schéma d'interdiction/challenge par défaut :

services.AddAuthentication(options =>
{
    options.DefaultChallengeScheme = "scheme name";

    // you can also skip this to make the challenge scheme handle the forbid as well
    options.DefaultForbidScheme = "scheme name";

    // of course you also need to register that scheme, e.g. using
    options.AddScheme<MySchemeHandler>("scheme name", "scheme display name");
});

MySchemeHandler doit mettre en œuvre IAuthenticationHandler et dans votre cas, vous devez surtout mettre en place ChallengeAsync y ForbidAsync :

public class MySchemeHandler : IAuthenticationHandler
{
    private HttpContext _context;

    public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
    {
        _context = context;
        return Task.CompletedTask;
    }

    public Task<AuthenticateResult> AuthenticateAsync()
        => Task.FromResult(AuthenticateResult.NoResult());

    public Task ChallengeAsync(AuthenticationProperties properties)
    {
        // do something
    }

    public Task ForbidAsync(AuthenticationProperties properties)
    {
        // do something
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X