diff --git a/zero.Core/Api/AuthenticationApi.cs b/zero.Core/Api/AuthenticationApi.cs index 664d5495..29d596b4 100644 --- a/zero.Core/Api/AuthenticationApi.cs +++ b/zero.Core/Api/AuthenticationApi.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; using Raven.Client.Documents; -using Raven.Client.Documents.Session; +using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using zero.Core.Entities; @@ -12,34 +14,50 @@ namespace zero.Core.Api protected IHttpContextAccessor HttpContextAccessor { get; set; } + protected SignInManager SignInManager { get; private set; } - public AuthenticationApi(IDocumentStore raven, IHttpContextAccessor httpContextAccessor) + + public AuthenticationApi(IDocumentStore raven, IHttpContextAccessor httpContextAccessor, SignInManager signInManager) { Raven = raven; HttpContextAccessor = httpContextAccessor; + SignInManager = signInManager; } /// public bool IsLoggedIn() { - return HttpContextAccessor.HttpContext.User != null; + ClaimsPrincipal principal = HttpContextAccessor.HttpContext.User; + + bool isAuthenticated = principal.Identity.IsAuthenticated; + bool isZeroUser = principal.HasClaim(Constants.Auth.Claims.IsZero, Constants.Auth.Claims.IsZero); + + return isAuthenticated && isZeroUser; + } + + + /// + public async Task Login(string email, string password, bool isPersistent) + { + SignInResult result = await SignInManager.PasswordSignInAsync(email, password, isPersistent, true); + + return result.Succeeded; + } + + + /// + public async Task Logout() + { + await SignInManager.SignOutAsync(); } /// public string GetUserId() { - return null; - //ResolveIdFromClaimsPrincipal(HttpContextAccessor.HttpContext.User); - } - - - /// - public async Task GetUser() - { - await Task.Delay(0); - return null; + ClaimsPrincipal principal = HttpContextAccessor.HttpContext.User; + return principal.Claims.FirstOrDefault(x => x.Type == Constants.Auth.Claims.UserId)?.Value; } } @@ -51,14 +69,19 @@ namespace zero.Core.Api /// bool IsLoggedIn(); + /// + /// Logs a zero-user in and sets cookie + /// + Task Login(string email, string password, bool isPersistent); + + /// + /// Logs out the current user + /// + Task Logout(); + /// /// Get the ID of the currently logged in user /// string GetUserId(); - - /// - /// Get the currently logged-in user (or null if not logged in) - /// - Task GetUser(); } } diff --git a/zero.Core/Api/UserApi.cs b/zero.Core/Api/UserApi.cs new file mode 100644 index 00000000..0f7055e8 --- /dev/null +++ b/zero.Core/Api/UserApi.cs @@ -0,0 +1,67 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; +using Raven.Client.Documents; +using System.Threading.Tasks; +using zero.Core.Entities; + +namespace zero.Core.Api +{ + public class UserApi : IUserApi + { + protected IDocumentStore Raven { get; private set; } + + protected IHttpContextAccessor HttpContextAccessor { get; set; } + + protected UserManager UserManager { get; private set; } + + + public UserApi(IDocumentStore raven, IHttpContextAccessor httpContextAccessor, UserManager userManager) + { + Raven = raven; + HttpContextAccessor = httpContextAccessor; + UserManager = userManager; + } + + /// + public async Task GetUser() + { + User user = await UserManager.GetUserAsync(HttpContextAccessor.HttpContext.User); + return user; + } + + + /// + public async Task GetUserById(string id) + { + User user = await UserManager.FindByIdAsync(id); + return user; + } + + + /// + public async Task GetUserByEmail(string email) + { + User user = await UserManager.FindByEmailAsync(email); + return user; + } + } + + + public interface IUserApi + { + /// + /// Get currently logged-in user + /// + Task GetUser(); + + /// + /// Find user by id + /// + Task GetUserById(string id); + + /// + /// Find user by email + /// + Task GetUserByEmail(string email); + } +} diff --git a/zero.Core/Auth/ZeroAuthorizeAttribute.cs b/zero.Core/Auth/ZeroAuthorizeAttribute.cs index 335caa49..e919a886 100644 --- a/zero.Core/Auth/ZeroAuthorizeAttribute.cs +++ b/zero.Core/Auth/ZeroAuthorizeAttribute.cs @@ -1,48 +1,64 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; using System; +using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; namespace zero.Core.Auth { public class ZeroAuthorizeAttribute : TypeFilterAttribute { - - public ZeroAuthorizeAttribute(string name) : base(typeof(ZeroAuthorizeFilter)) + + public ZeroAuthorizeAttribute() : this(String.Empty, true) { } + + public ZeroAuthorizeAttribute(bool enabled) : this(String.Empty, enabled) { } + + public ZeroAuthorizeAttribute(string name, bool enabled) : base(typeof(ZeroAuthorizeFilter)) { - Arguments = new object[] { name }; + Arguments = new object[] { name, enabled }; } } - public class ZeroAuthorizeFilter : AuthorizeFilter + public class ZeroAuthorizeFilter : IAuthorizationFilter { string Name { get; set; } + bool Enabled { get; set; } - public ZeroAuthorizeFilter(string name) + + public ZeroAuthorizeFilter(string name, bool enabled) : base() { Name = name; + Enabled = enabled; } - //public ZeroAuthorizeFilter(IAuthorizationPolicyProvider provider) - // : base(provider, new[] { new AuthorizeData(Constants.AzureAdPolicy) }) { } - public override async Task OnAuthorizationAsync(AuthorizationFilterContext context) + public void OnAuthorization(AuthorizationFilterContext context) { - await Task.Delay(0); - //await base.OnAuthorizationAsync(context); + Console.WriteLine("zeroauthorize: " + (Name ?? "[empty]")); - Console.WriteLine("zeroauthorize: " + Name); + // allow anonymous skips all authorization + if (context.Filters.Any(item => item is IAllowAnonymousFilter) || !Enabled) + { + return; + } - context.Result = new AcceptedResult(); - //context.Result = new ForbidResult(); - //await base.OnAuthorizationAsync(context); + var httpContext = context.HttpContext; + var authService = httpContext.RequestServices.GetRequiredService(); - //var username = context.HttpContext.User.Identity.Name; + ClaimsPrincipal user = context.HttpContext.User; - //Console.WriteLine($"{username} just logged in!"); - + bool isAuthenticated = user.Identity.IsAuthenticated; + bool isZeroUser = user.HasClaim(Constants.Auth.Claims.IsZero, Constants.Auth.Claims.IsZero); + + if (!isAuthenticated || !isZeroUser) + { + context.Result = new StatusCodeResult(401); + } } } } diff --git a/zero.Core/Constants.cs b/zero.Core/Constants.cs index e37a1462..05b9b8d4 100644 --- a/zero.Core/Constants.cs +++ b/zero.Core/Constants.cs @@ -7,6 +7,19 @@ public const string Scheme = "zeroCookies"; public const string CookieName = "zero.session"; + + public static class Claims + { + public const string IsZero = "zero.claim.iszero"; + + public const string UserId = "zero.claim.userid"; + + public const string UserName = "zero.claim.username"; + + public const string RoleId = "zero.claim.roleid"; + + public const string SecurityStamp = "zero.claim.securitystamp"; + } } public static class Database diff --git a/zero.Core/Extensions/StringExtensions.cs b/zero.Core/Extensions/StringExtensions.cs index ea535749..c8af54dd 100644 --- a/zero.Core/Extensions/StringExtensions.cs +++ b/zero.Core/Extensions/StringExtensions.cs @@ -30,6 +30,12 @@ namespace zero.Core.Extensions } + public static string EnsureSurroundedWith(this string input, char toSurroundWith) + { + return input.EnsureStartsWith(toSurroundWith).EnsureEndsWith(toSurroundWith); + } + + public static string TrimEnd(this string value, string forRemoving) { if (String.IsNullOrEmpty(value)) return value; diff --git a/zero.Core/Identity/UserStore.Email.cs b/zero.Core/Identity/UserStore.Email.cs index 5ae63806..5fd56261 100644 --- a/zero.Core/Identity/UserStore.Email.cs +++ b/zero.Core/Identity/UserStore.Email.cs @@ -43,7 +43,7 @@ namespace zero.Core.Identity /// public Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken) { - user.Email = email; + user.Email = email.ToLowerInvariant(); return Task.CompletedTask; } @@ -59,7 +59,7 @@ namespace zero.Core.Identity /// public Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken) { - user.Email = normalizedEmail; + user.Email = normalizedEmail.ToLowerInvariant(); return Task.CompletedTask; } } diff --git a/zero.Core/Identity/UserStore.cs b/zero.Core/Identity/UserStore.cs index a7388892..533bd0c0 100644 --- a/zero.Core/Identity/UserStore.cs +++ b/zero.Core/Identity/UserStore.cs @@ -93,11 +93,11 @@ namespace zero.Core.Identity /// - public Task FindByIdAsync(string userId, CancellationToken cancellationToken) + public async Task FindByIdAsync(string userId, CancellationToken cancellationToken) { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return session.LoadAsync(userId); + return await session.LoadAsync(userId); } } diff --git a/zero.Web/Controllers/ApplicationsController.cs b/zero.Web/Controllers/ApplicationsController.cs index b25ac03f..93807dfe 100644 --- a/zero.Web/Controllers/ApplicationsController.cs +++ b/zero.Web/Controllers/ApplicationsController.cs @@ -6,7 +6,6 @@ using zero.Core.Api; namespace zero.Web.Controllers { - [AllowAnonymous] public class ApplicationsController : BackofficeController { private IApplicationsApi Api { get; set; } diff --git a/zero.Web/Controllers/AuthenticationController.cs b/zero.Web/Controllers/AuthenticationController.cs index 28be111d..5295e80e 100644 --- a/zero.Web/Controllers/AuthenticationController.cs +++ b/zero.Web/Controllers/AuthenticationController.cs @@ -4,11 +4,11 @@ using System; using System.Threading.Tasks; using zero.Core; using zero.Core.Api; -using zero.Core.Entities; +using zero.Core.Auth; namespace zero.Web.Controllers { - [AllowAnonymous] + [ZeroAuthorize] public class AuthenticationController : BackofficeController { private IAuthenticationApi Api { get; set; } @@ -22,8 +22,6 @@ namespace zero.Web.Controllers /// /// Get the currently logged in user /// - [AllowAnonymous] - //[Authorize()] public async Task GetUser() { return Json(await Api.GetUser()); diff --git a/zero.Web/Controllers/BackofficeController.cs b/zero.Web/Controllers/BackofficeController.cs index 34c27315..0e3492bd 100644 --- a/zero.Web/Controllers/BackofficeController.cs +++ b/zero.Web/Controllers/BackofficeController.cs @@ -1,8 +1,10 @@ using Microsoft.AspNetCore.Mvc; using zero.Core; +using zero.Core.Auth; namespace zero.Web.Controllers { + [ZeroAuthorize] public abstract class BackofficeController : Controller { protected IZeroConfiguration Configuration { get; set; } diff --git a/zero.Web/Controllers/CountriesController.cs b/zero.Web/Controllers/CountriesController.cs index cc00c270..ad3da8bc 100644 --- a/zero.Web/Controllers/CountriesController.cs +++ b/zero.Web/Controllers/CountriesController.cs @@ -6,7 +6,6 @@ using zero.Core.Api; namespace zero.Web.Controllers { - [AllowAnonymous] public class CountriesController : BackofficeController { private ICountriesApi Api { get; set; } diff --git a/zero.Web/Controllers/IndexController.cs b/zero.Web/Controllers/IndexController.cs index 63db1fad..3f6740f1 100644 --- a/zero.Web/Controllers/IndexController.cs +++ b/zero.Web/Controllers/IndexController.cs @@ -2,11 +2,12 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using zero.Core; +using zero.Core.Auth; using zero.Core.Extensions; namespace zero.Web.Controllers { - [AllowAnonymous] + [ZeroAuthorize(false)] public class IndexController : BackofficeController { private ZeroOptions Options { get; set; } diff --git a/zero.Web/Controllers/PageTreeController.cs b/zero.Web/Controllers/PageTreeController.cs index 5784c0ae..5bb777ab 100644 --- a/zero.Web/Controllers/PageTreeController.cs +++ b/zero.Web/Controllers/PageTreeController.cs @@ -7,7 +7,6 @@ using zero.Core.Api; namespace zero.Web.Controllers { - [AllowAnonymous] public class PageTreeController : BackofficeController { private IPageTreeApi Api { get; set; } diff --git a/zero.Web/Controllers/SectionsController.cs b/zero.Web/Controllers/SectionsController.cs index 3de8c76e..bd58dc3c 100644 --- a/zero.Web/Controllers/SectionsController.cs +++ b/zero.Web/Controllers/SectionsController.cs @@ -5,7 +5,6 @@ using zero.Core.Api; namespace zero.Web.Controllers { - [AllowAnonymous] public class SectionsController : BackofficeController { private ISectionsApi Api { get; set; } diff --git a/zero.Web/Controllers/SettingsController.cs b/zero.Web/Controllers/SettingsController.cs index f6b67591..d9f93fa5 100644 --- a/zero.Web/Controllers/SettingsController.cs +++ b/zero.Web/Controllers/SettingsController.cs @@ -5,7 +5,6 @@ using zero.Core.Api; namespace zero.Web.Controllers { - [AllowAnonymous] public class SettingsController : BackofficeController { private ISettingsApi Api { get; set; } diff --git a/zero.Web/Controllers/SetupController.cs b/zero.Web/Controllers/SetupController.cs index 63be9c15..9e3e0ecc 100644 --- a/zero.Web/Controllers/SetupController.cs +++ b/zero.Web/Controllers/SetupController.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using System; @@ -8,6 +6,7 @@ using System.Linq; using System.Threading.Tasks; using zero.Core; using zero.Core.Api; +using zero.Core.Auth; using zero.Core.Entities; using zero.Core.Entities.Setup; using zero.Core.Extensions; @@ -15,7 +14,7 @@ using zero.Web.Controllers; namespace zero.Web.Setup { - [AllowAnonymous] + [ZeroAuthorize(false)] public class SetupController : BackofficeController { protected ISetupApi Api { get; private set; } @@ -32,6 +31,7 @@ namespace zero.Web.Setup Options = options.CurrentValue; } + public IActionResult Index() { if (!Configuration.ZeroVersion.IsNullOrEmpty()) @@ -42,6 +42,7 @@ namespace zero.Web.Setup return View("/Views/Setup.cshtml"); } + [HttpPost] public async Task Install([FromBody] SetupModel model) { diff --git a/zero.Web/Controllers/TestController.cs b/zero.Web/Controllers/TestController.cs index 7a729991..41686d35 100644 --- a/zero.Web/Controllers/TestController.cs +++ b/zero.Web/Controllers/TestController.cs @@ -1,5 +1,4 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; using zero.Core; @@ -23,15 +22,6 @@ namespace zero.Web.Controllers } - [HttpGet] - public IActionResult GetUser() - { - return Json(new - { - user = HttpContext.User.Identity.IsAuthenticated - }); - } - [HttpPost] public async Task Login([FromQuery] string username, [FromQuery] string password) { @@ -44,5 +34,29 @@ namespace zero.Web.Controllers result }); } + + + [ZeroAuthorize] + public async Task GetUser() + { + User user = await SignInManager.UserManager.GetUserAsync(HttpContext.User); + + return Json(new + { + user + }); + } + + + [HttpPost] + public async Task Logout() + { + await SignInManager.SignOutAsync(); + + return Json(new + { + success = true + }); + } } } diff --git a/zero.Web/Models/LoginModel.cs b/zero.Web/Models/LoginModel.cs new file mode 100644 index 00000000..069b055e --- /dev/null +++ b/zero.Web/Models/LoginModel.cs @@ -0,0 +1,11 @@ +namespace zero.Web.Models +{ + public class LoginModel + { + public string Email { get; set; } + + public string Password { get; set; } + + public bool IsPersistent { get; set; } = true; + } +} diff --git a/zero.Web/Startup.cs b/zero.Web/Startup.cs index 91a9ca4b..ef7cebab 100644 --- a/zero.Web/Startup.cs +++ b/zero.Web/Startup.cs @@ -1,4 +1,3 @@ -using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -13,10 +12,8 @@ using Newtonsoft.Json.Serialization; using Raven.Client.Documents; using Raven.Client.Documents.Conventions; using System; -using System.Threading.Tasks; using zero.Core; using zero.Core.Api; -using zero.Core.Entities; using zero.Core.Extensions; namespace zero.Web @@ -123,6 +120,7 @@ namespace zero.Web services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } /// @@ -153,34 +151,11 @@ namespace zero.Web //app.UseCors(); - app.UseWhen(ctx => ctx.Request.Path.ToString().StartsWith(zeroPath.TrimEnd('/')), zeroApp => + app.UseZero(); + + app.Run(async (context) => { - zeroApp.UseRouting(); - zeroApp.UseAuthentication(); - zeroApp.UseAuthorization(); - - zeroApp.UseEndpoints(endpoints => - { - // setup route - endpoints.MapControllerRoute( - name: "setup", - pattern: zeroPath + "setup", - defaults: new - { - controller = "Setup", - action = "Index" - } - ); - - // routes for API - endpoints.MapControllerRoute( - name: "api", - pattern: zeroPath + "api/{controller=Index}/{action=Index}/{id?}" - ); - - // fallbacks for SPA - endpoints.MapFallbackToController(zeroPath + "{**path}", "Index", "Index"); - }); + await context.Response.WriteAsync("from app"); }); } } diff --git a/zero.Web/ZeroApplicationBuilderExtensions.cs b/zero.Web/ZeroApplicationBuilderExtensions.cs new file mode 100644 index 00000000..ee3cffa2 --- /dev/null +++ b/zero.Web/ZeroApplicationBuilderExtensions.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using zero.Core; +using zero.Core.Extensions; + +namespace zero.Web +{ + public static class ZeroApplicationBuilderExtensions + { + public static IApplicationBuilder UseZero(this IApplicationBuilder app) + { + ZeroOptions options = app.ApplicationServices.GetService>().CurrentValue; + + string path = options.BackofficePath.EnsureStartsWith('/').TrimEnd('/'); + + // map backoffice + //app.UseWhen() + app.UseWhen(ctx => ctx.Request.Path.ToString().StartsWith(path), builder => + { + builder.UseRouting(); + + builder.UseAuthentication(); + builder.UseAuthorization(); + + //builder.UseMiddleware(options); + + builder.UseEndpoints(endpoints => + { + // setup route + endpoints.MapControllerRoute( + name: "setup", + pattern: path + "/setup", + defaults: new + { + controller = "Setup", + action = "Index" + } + ); + + // routes for API + endpoints.MapControllerRoute( + name: "api", + pattern: path + "/api/{controller}/{action}/{id?}" + ); + + // fallbacks for SPA + endpoints.MapFallbackToController(path + "/{**path}", "Index", "Index"); + }); + }); + + return app; + } + + //public static ZeroBuilder AddZero(this IApplicationBuilder app, Action setupAction) + //{ + // return services.AddZero().WithOptions(setupAction); + //} + } +} diff --git a/zero.Web/ZeroBuilder.cs b/zero.Web/ZeroBuilder.cs index 0098b867..de67b490 100644 --- a/zero.Web/ZeroBuilder.cs +++ b/zero.Web/ZeroBuilder.cs @@ -25,18 +25,25 @@ namespace zero.Web Services.AddIdentity(opts => { + opts.ClaimsIdentity.UserIdClaimType = Constants.Auth.Claims.UserId; + opts.ClaimsIdentity.UserNameClaimType = Constants.Auth.Claims.UserName; + opts.ClaimsIdentity.RoleClaimType = Constants.Auth.Claims.RoleId; + opts.ClaimsIdentity.SecurityStampClaimType = Constants.Auth.Claims.SecurityStamp; + opts.Password.RequireDigit = false; opts.Password.RequireLowercase = false; opts.Password.RequireUppercase = false; opts.Password.RequireNonAlphanumeric = false; - opts.Password.RequiredLength = 12; + opts.Password.RequiredLength = 8; opts.Password.RequiredUniqueChars = 1; opts.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); opts.Lockout.MaxFailedAccessAttempts = 5; opts.Lockout.AllowedForNewUsers = true; - }).AddDefaultTokenProviders(); + }) + .AddClaimsPrincipalFactory() + .AddDefaultTokenProviders(); Services.ConfigureApplicationCookie(opts => { diff --git a/zero.Web/ZeroClaimsPrinicipalFactory.cs b/zero.Web/ZeroClaimsPrinicipalFactory.cs new file mode 100644 index 00000000..9c0f5ffb --- /dev/null +++ b/zero.Web/ZeroClaimsPrinicipalFactory.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Options; +using System.Security.Claims; +using System.Threading.Tasks; +using zero.Core; +using zero.Core.Entities; + +namespace zero.Web +{ + public class ZeroClaimsPrinicipalFactory : UserClaimsPrincipalFactory + { + public ZeroClaimsPrinicipalFactory(UserManager userManager, RoleManager roleManager, IOptions optionsAccessor) : base(userManager, roleManager, optionsAccessor) + { + + } + + public async override Task CreateAsync(User user) + { + ClaimsPrincipal principal = await base.CreateAsync(user); + + ((ClaimsIdentity)principal.Identity).AddClaim(new Claim(Constants.Auth.Claims.IsZero, Constants.Auth.Claims.IsZero)); + + return principal; + } + } +} diff --git a/zero.Web/ZeroMiddleware.cs b/zero.Web/ZeroMiddleware.cs new file mode 100644 index 00000000..a432ac1c --- /dev/null +++ b/zero.Web/ZeroMiddleware.cs @@ -0,0 +1,74 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Antiforgery; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; +using zero.Core; + +namespace zero.Web +{ + public class ZeroMiddleware + { + private RequestDelegate Next { get; set; } + private ZeroOptions Options { get; set; } + + + public ZeroMiddleware(RequestDelegate next, ZeroOptions options) + { + Next = next; + Options = options; + } + + + public async Task Invoke(HttpContext httpContext) + { + await httpContext.Response.WriteAsync("from zero"); + //var context = null; // new AspNetCoreDashboardContext(_storage, _options, httpContext); + //var findResult = Routes.FindDispatcher(httpContext.Request.Path.Value); + + //if (findResult == null) + //{ + // await Next.Invoke(httpContext); + // return; + //} + + // ReSharper disable once LoopCanBeConvertedToQuery + //foreach (var filter in Options.Authorization) + //{ + // if (!filter.Authorize(context)) + // { + // var isAuthenticated = httpContext.User?.Identity?.IsAuthenticated; + + // httpContext.Response.StatusCode = isAuthenticated == true + // ? (int)HttpStatusCode.Forbidden + // : (int)HttpStatusCode.Unauthorized; + + // return; + // } + //} + + //if (!_options.IgnoreAntiforgeryToken) + //{ + // var antiforgery = httpContext.RequestServices.GetService(); + + // if (antiforgery != null) + // { + // var requestValid = await antiforgery.IsRequestValidAsync(httpContext); + + // if (!requestValid) + // { + // // Invalid or missing CSRF token + // httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + // return; + // } + // } + //} + + //context.UriMatch = findResult.Item2; + + //await findResult.Item1.Dispatch(context); + } + } +} \ No newline at end of file