Alors, après une longue journée à essayer de résoudre ce problème, j'ai enfin compris comment Microsoft veut nous faire de la coutume de l'authentification des gestionnaires pour leur nouveau single-middleware d'installation dans le noyau 2.0.
Après en regardant à travers une partie de la documentation sur MSDN, j'ai trouvé une classe appelée AuthenticationHandler<TOption>
qui implémente l' IAuthenticationHandler
interface.
À partir de là, j'ai trouvé l'ensemble d'une base de code existante schémas d'authentification situé à https://github.com/aspnet/Security
À l'intérieur de l'un de ces, il montre comment Microsoft implémente les JwtBearer schéma d'authentification. (https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer)
J'ai copié la plupart de ce code dans un nouveau dossier, et effacé toutes les choses ayant à voir avec JwtBearer
.
Dans l' JwtBearerHandler
de la classe (qui s'étend AuthenticationHandler<>
), il y a un remplacement pour Task<AuthenticateResult> HandleAuthenticateAsync()
J'ai ajouté dans notre ancien middleware pour la mise en place des réclamations par le biais d'un token personnalisé serveur, et était toujours face à quelques problèmes avec les autorisations, tout en crachant un 200 OK
au lieu de 401 Unauthorized
lorsqu'un jeton n'était pas valide et aucune réclamation ont été mis en place.
J'ai réalisé que j'avais remplacé Task HandleChallengeAsync(AuthenticationProperties properties)
qui, pour quelque raison que ce soit est utilisé pour définir des autorisations via [Authorize(Roles="")]
dans un contrôleur.
Après la suppression de cette substitution, le code a fonctionné, et avait réussi à jeter un 401
lorsque les autorisations ne correspondent pas.
Le principal à retenir de cela, c'est que maintenant vous ne pouvez pas utiliser un middleware, vous avez à mettre en œuvre par AuthenticationHandler<>
et vous devez régler l' DefaultAuthenticateScheme
et DefaultChallengeScheme
lors de l'utilisation d' services.AddAuthentication(...)
.
Voici un exemple de ce à quoi cela ressemble:
En Démarrage.cs / ConfigureServices (), ajoutez:
services.AddAuthentication(options =>
{
// the scheme name has to match the value we're going to use in AuthenticationBuilder.AddScheme(...)
options.DefaultAuthenticateScheme = "Custom Scheme";
options.DefaultChallengeScheme = "Custom Scheme";
})
.AddCustomAuth(o => { });
En Démarrage.cs / Configure (), ajoutez:
app.UseAuthentication();
Créer un nouveau fichier CustomAuthExtensions.cs
public static class CustomAuthExtensions
{
public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
{
return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
}
}
Créer un nouveau fichier CustomAuthOptions.cs
public class CustomAuthOptions: AuthenticationSchemeOptions
{
public CustomAuthOptions()
{
}
}
Créer un nouveau fichier CustomAuthHandler.cs
internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
// store custom services here...
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
// build the claims and put them in "Context"; you need to import the Microsoft.AspNetCore.Authentication package
return AuthenticateResult.NoResult();
}
}