diff --git a/src/AuthSamples/build/dependencies.props b/src/AuthSamples/build/dependencies.props index e123d854cc..3a8c0ce7c3 100644 --- a/src/AuthSamples/build/dependencies.props +++ b/src/AuthSamples/build/dependencies.props @@ -5,32 +5,32 @@ 0.9.9 3.0.0-alpha1-20181031.6 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 3.0.0-a-alpha1-authz-middleware-16949 3.0.0-a-alpha1-authz-middleware-16949 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 - 3.0.0-alpha1-10717 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 + 3.0.0-alpha1-10772 3.0.0-preview-181106-14 2.2.1 2.3.2 @@ -61,10 +61,10 @@ 2.0.9 2.1.3 3.0.0-preview1-26907-05 - 3.0.0-alpha1-10717 + 3.0.0-alpha1-10772 15.6.1 3.0.1 - 3.0.0-alpha1-10717 + 3.0.0-alpha1-10772 4.10.0 2.0.3 4.6.0-preview1-26907-04 diff --git a/src/AuthSamples/samples/StaticFilesAuth/Startup.cs b/src/AuthSamples/samples/StaticFilesAuth/Startup.cs index 9077cd9433..91fef94b9e 100644 --- a/src/AuthSamples/samples/StaticFilesAuth/Startup.cs +++ b/src/AuthSamples/samples/StaticFilesAuth/Startup.cs @@ -1,12 +1,13 @@ -using System; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; -using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Endpoints; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -49,27 +50,23 @@ namespace StaticFilesAuth { return false; } - var userPath = Path.Combine(usersPath, userName); - if (context.Resource is IFileInfo file) + if (context.Resource is Endpoint endpoint) { - var path = Path.GetDirectoryName(file.PhysicalPath); - return string.Equals(path, basePath, StringComparison.OrdinalIgnoreCase) - || string.Equals(path, usersPath, StringComparison.OrdinalIgnoreCase) - || string.Equals(path, userPath, StringComparison.OrdinalIgnoreCase) - || path.StartsWith(userPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); - } - else if (context.Resource is IDirectoryContents dir) - { - // https://github.com/aspnet/Home/issues/3073 - // This won't work right if the directory is empty - var path = Path.GetDirectoryName(dir.First().PhysicalPath); - return string.Equals(path, basePath, StringComparison.OrdinalIgnoreCase) - || string.Equals(path, usersPath, StringComparison.OrdinalIgnoreCase) - || string.Equals(path, userPath, StringComparison.OrdinalIgnoreCase) - || path.StartsWith(userPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); + var userPath = Path.Combine(usersPath, userName); + + var directory = endpoint.Metadata.GetMetadata(); + if (directory != null) + { + return string.Equals(directory.FullName, basePath, StringComparison.OrdinalIgnoreCase) + || string.Equals(directory.FullName, usersPath, StringComparison.OrdinalIgnoreCase) + || string.Equals(directory.FullName, userPath, StringComparison.OrdinalIgnoreCase) + || directory.FullName.StartsWith(userPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); + } + + throw new InvalidOperationException($"Missing file system metadata."); } - throw new NotImplementedException($"Unknown resource type '{context.Resource.GetType()}'"); + throw new InvalidOperationException($"Unknown resource type '{context.Resource.GetType()}'"); }); }); }); @@ -98,12 +95,15 @@ namespace StaticFilesAuth app.Map("/MapAuthenticatedFiles", branch => { - MapAuthenticatedFiles(branch, files); + branch.Use((context, next) => { SetFileEndpoint(context, files, null); return next(); }); + branch.UseAuthorization(); + SetupFileServer(branch, files); }); - app.Map("/MapImperativeFiles", branch => { - MapImperativeFiles(authorizationService, branch, files); + branch.Use((context, next) => { SetFileEndpoint(context, files, "files"); return next(); }); + branch.UseAuthorization(); + SetupFileServer(branch, files); }); app.UseMvc(routes => @@ -114,81 +114,51 @@ namespace StaticFilesAuth }); } - // Blanket authorization, any authenticated user is allowed access to these resources. - private static void MapAuthenticatedFiles(IApplicationBuilder branch, PhysicalFileProvider files) + private void SetupFileServer(IApplicationBuilder builder, IFileProvider files) { - branch.Use(async (context, next) => - { - if (!context.User.Identity.IsAuthenticated) - { - await context.ChallengeAsync(new AuthenticationProperties() - { - // https://github.com/aspnet/Security/issues/1730 - // Return here after authenticating - RedirectUri = context.Request.PathBase + context.Request.Path + context.Request.QueryString - }); - return; - } - - await next(); - }); - branch.UseFileServer(new FileServerOptions() + builder.UseFileServer(new FileServerOptions() { EnableDirectoryBrowsing = true, FileProvider = files }); } - // Policy based authorization, requests must meet the policy criteria to be get access to the resources. - private static void MapImperativeFiles(IAuthorizationService authorizationService, IApplicationBuilder branch, PhysicalFileProvider files) + private static void SetFileEndpoint(HttpContext context, PhysicalFileProvider files, string policy) { - branch.Use(async (context, next) => + var fileSystemPath = GetFileSystemPath(files, context.Request.Path); + if (fileSystemPath != null) { - var fileInfo = files.GetFileInfo(context.Request.Path); - AuthorizationResult result = null; - if (fileInfo.Exists) - { - result = await authorizationService.AuthorizeAsync(context.User, fileInfo, "files"); - } - else - { - // https://github.com/aspnet/Home/issues/2537 - var dir = files.GetDirectoryContents(context.Request.Path); - if (dir.Exists) - { - result = await authorizationService.AuthorizeAsync(context.User, dir, "files"); - } - else - { - context.Response.StatusCode = StatusCodes.Status404NotFound; - return; - } - } + var metadata = new List(); + metadata.Add(new DirectoryInfo(Path.GetDirectoryName(fileSystemPath))); + metadata.Add(new AuthorizeAttribute(policy)); - if (!result.Succeeded) - { - if (!context.User.Identity.IsAuthenticated) - { - await context.ChallengeAsync(new AuthenticationProperties() - { - // https://github.com/aspnet/Security/issues/1730 - // Return here after authenticating - RedirectUri = context.Request.PathBase + context.Request.Path + context.Request.QueryString - }); - return; - } - // Authenticated but not authorized - await context.ForbidAsync(); - return; - } + var endpoint = new Endpoint( + c => throw new InvalidOperationException("Static file middleware should return file request."), + new EndpointMetadataCollection(metadata), + context.Request.Path); - await next(); - }); - branch.UseFileServer(new FileServerOptions() + context.SetEndpoint(endpoint); + } + } + + private static string GetFileSystemPath(PhysicalFileProvider files, string path) + { + var fileInfo = files.GetFileInfo(path); + if (fileInfo.Exists) { - EnableDirectoryBrowsing = true, - FileProvider = files - }); + return Path.Join(files.Root, path); + } + else + { + // https://github.com/aspnet/Home/issues/2537 + var dir = files.GetDirectoryContents(path); + if (dir.Exists) + { + return Path.Join(files.Root, path); + } + } + + return null; } } } diff --git a/src/AuthSamples/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj b/src/AuthSamples/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj index 7fe45b5ff6..8d75e69122 100644 --- a/src/AuthSamples/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj +++ b/src/AuthSamples/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.0