Ich habe versucht, eine Ajax-Version des ValidateAntiForgeryToken neu zu erstellen - es gibt viele Blog-Posts, wie dies für frühere Versionen von MVC, aber mit der neuesten MVC 6, keine der Code ist relevant. Das Kernprinzip, dem ich nachgehe, ist jedoch, dass die Validierung den Cookie und den Header für die __RequestVerificationToken
betrachtet, anstatt den Cookie mit einem Formularwert zu vergleichen. Ich verwende MVC 6.0.0-rc1-final, dnx451-Framework, und alle Microsoft.Extensions-Bibliotheken sind 1.0.0-rc1-final.ValidateAntiForgeryToken in Ajax Anfrage mit AspNet Core MVC
Mein erster Gedanke war, nur zu erben ValidateAntiForgeryTokenAttribute, aber mit Blick auf den Quellcode, würde ich meine eigene Implementierung eines Authorization Filter zurückgeben müssen, um es auf den Header zu sehen.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class ValidateAjaxAntiForgeryTokenAttribute : Attribute, IFilterFactory, IFilterMetadata, IOrderedFilter { public int Order { get; set; } public bool IsReusable => true; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { return serviceProvider.GetRequiredService<ValidateAjaxAntiforgeryTokenAuthorizationFilter>(); } }
Als solche habe ich dann meine eigene Version von ValidateAntiforgeryTokenAuthorizationFilter
public class ValidateAjaxAntiforgeryTokenAuthorizationFilter : IAsyncAuthorizationFilter, IAntiforgeryPolicy { private readonly IAntiforgery _antiforgery; private readonly ILogger _logger; public ValidateAjaxAntiforgeryTokenAuthorizationFilter(IAntiforgery antiforgery, ILoggerFactory loggerFactory) { if (antiforgery == null) { throw new ArgumentNullException(nameof(antiforgery)); } _antiforgery = antiforgery; _logger = loggerFactory.CreateLogger<ValidateAjaxAntiforgeryTokenAuthorizationFilter>(); } public async Task OnAuthorizationAsync(AuthorizationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (IsClosestAntiforgeryPolicy(context.Filters) && ShouldValidate(context)) { try { await _antiforgery.ValidateRequestAsync(context.HttpContext); } catch (AjaxAntiforgeryValidationException exception) { _logger.LogInformation(1, string.Concat("Ajax Antiforgery token validation failed. ", exception.Message)); context.Result = new BadRequestResult(); } } } protected virtual bool ShouldValidate(AuthorizationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } return true; } private bool IsClosestAntiforgeryPolicy(IList<IFilterMetadata> filters) { // Determine if this instance is the 'effective' antiforgery policy. for (var i = filters.Count - 1; i >= 0; i--) { var filter = filters[i]; if (filter is IAntiforgeryPolicy) { return object.ReferenceEquals(this, filter); } } Debug.Fail("The current instance should be in the list of filters."); return false; } }
Allerdings habe ich nicht die richtige Nuget Paket und Namespace, IAntiforgeryPolicy enthält finden können. Während ich das Interface auf GitHub gefunden habe - in welchem Paket finde ich es?
Mein nächster Versuch war, stattdessen nach der IAntiforgery Injektion zu gehen, und ersetzen Sie die DefaultAntiforgery durch meine eigene AjaxAntiforgery
.
public class AjaxAntiforgery : DefaultAntiforgery { private readonly AntiforgeryOptions _options; private readonly IAntiforgeryTokenGenerator _tokenGenerator; private readonly IAntiforgeryTokenSerializer _tokenSerializer; private readonly IAntiforgeryTokenStore _tokenStore; private readonly ILogger<AjaxAntiforgery> _logger; public AjaxAntiforgery( IOptions<AntiforgeryOptions> antiforgeryOptionsAccessor, IAntiforgeryTokenGenerator tokenGenerator, IAntiforgeryTokenSerializer tokenSerializer, IAntiforgeryTokenStore tokenStore, ILoggerFactory loggerFactory) { _options = antiforgeryOptionsAccessor.Value; _tokenGenerator = tokenGenerator; _tokenSerializer = tokenSerializer; _tokenStore = tokenStore; _logger = loggerFactory.CreateLogger<AjaxAntiforgery>(); } }
bekam ich so weit, bevor ich heraus ins Stocken geraten, weil es keine generische Methode auf ILoggerFactory
für CreateLogger<T>()
ist. Der Quellcode für DefaultAntiforgery
hat Microsoft.Extensions.Options
, aber ich kann diesen Namespace in keinem Nuget-Paket finden. Microsoft.Extensions.OptionsModel
existiert, aber das bringt nur die IOptions<out TOptions>
Schnittstelle mit.
Um all dies zu folgen, sobald ich den Autorisierungsfilter zu arbeiten, oder ich bekomme eine neue Implementierung von IAntiforgery
, wo oder wie registriere ich es mit der Abhängigkeitsinjektion, um es zu verwenden - und nur für die Aktionen dass ich Ajax-Anfragen annehmen werde?
würden Sie ein Codebeispiel haben? – Grandizer