web-dev-qa-db-fra.com

ASP.Net core 2: schéma d'authentification par défaut ignoré

J'essaye de construire un AuthenticationHandler personnalisé dans ASP.Net Core 2. Suivi d'un sujet comme middleware d'authentification ASP.NET Core 2. et Pourquoi le schéma d'authentification Asp.Net Core est-il obligatoire =, J'ai créé les classes spécifiques. L'enregistrement se déroule comme ceci:

services.AddAuthentication(
    options =>
    {
        options.DefaultScheme = Constants.NoOpSchema;
        options.DefaultAuthenticateScheme = Constants.NoOpSchema;
        options.DefaultChallengeScheme = Constants.NoOpSchema;
        options.DefaultSignInScheme = Constants.NoOpSchema;
        options.DefaultSignOutScheme = Constants.NoOpSchema; 
        options.DefaultForbidScheme = Constants.NoOpSchema;
    }
).AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });

Tout fonctionne, si les contrôleurs spécifiques définissent explicitement le schéma:

[Authorize(AuthenticationSchemes= Constants.NoOpSchema)]
[Route("api/[controller]")]
public class IndividualsController : Controller

Mais je voudrais ne pas avoir à définir le schéma, car il devrait être ajouté dynamiquement. Dès que je supprime la propriété Scheme, comme ceci:

[Authorize]
[Route("api/[controller]")]
public class IndividualsController : Controller

Ça ne marche plus.

J'aurais espéré que la définition des propriétés DefaultScheme fasse ce travail. Assez intéressant, je n'ai trouvé aucune discussion spécifique sur ce sujet. Suis-je en train de faire quelque chose de mal ici ou mon résultat escompté est-il mauvais?

Edit: Merci pour les questions, cela m'a beaucoup aidé. Il semble que le mappage que DefaultScheme utilise par le middleware d'authentification, que je n'ai utilisé que lorsque CustomAuthHandler n'était pas en place. Par conséquent, j'ai toujours dû ajouter AuthenticationMiddleware.

Edit2: Malheureusement, cela ne fonctionne toujours pas. Pour améliorer un peu ma question: j'ajoute le middleware comme d'habitude:

app.UseAuthentication();
app.UseMvc();

Maintenant, j'entre dans mon gestionnaire, qui ressemble à ceci:

public class NoOpAuthHandler : AuthenticationHandler<NoOpAuthOptions>
{
    public const string NoOpSchema = "NoOp";

    public NoOpAuthHandler(IOptionsMonitor<NoOpAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync() => Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, NoOpSchema)));
}

Mais même si je retourne toujours le succès, j'obtiens un 401. Je pense que je dois creuser plus profondément et définir des revendications, mais malheureusement, les gestionnaires de Microsoft sont assez difficiles à analyser, car ils contiennent beaucoup de code.

14
Matthias Müller

Réponse ASP.Net Core 2

Vous devez définir une stratégie d'autorisation par défaut liée à votre schéma d'authentification:

services.AddAuthorization(options => {
  options.DefaultPolicy = new AuthorizationPolicyBuilder()
    .AddAuthenticationSchemes(Constants.NoOpSchema)
    .RequireAuthenticatedUser()
    .Build();
});

Réponse ASP.Net Core

Dans ASP.Net Core 3, les choses ont apparemment changé un peu, vous devriez donc créer une méthode d'extension pour ajouter votre gestionnaire d'authentification:

public static class NoOpAuthExtensions
{
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, _ => { });
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(authenticationScheme, null, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<NoOpAuthOptions> configureOptions)
    {
        return builder.AddScheme<NoOpAuthOptions, NoOpAuthHandler>(authenticationScheme, displayName, configureOptions);
    }
}

Et utilisez-le dans votre méthode ConfigureServices comme ceci:

services
  .AddAuthentication(NoOpAuthHandler.NoOpSchema)
  .AddNoOpAuth();
12
RaphaelH

Assurez-vous que vous disposez d'un middleware d'authentification dans votre pipeline et placez-le avant MVC.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ///

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });
    ///
}

MISE À JOUR

essayez d'utiliser ce code dans la méthode HandleAuthenticateAsync.

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    List<Claim> claims = new List<Claim>();
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
    ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);
    return AuthenticateResult.Success(authenticationTicket);
}
10
Kahbazi

essaye ça.

services.AddAuthentication(
        options =>
        {
            options.DefaultAuthenticateScheme = "Cookie"
            options.DefaultChallengeScheme = Constants.NoOpSchema;
            options.DefaultSignInScheme = "Cookie";
        }
    )
    .AddCookie("Cookie")
    .AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });
0
Oleg