Update static files sample to use AuthZ middleware (#4279)

This commit is contained in:
James Newton-King 2018-12-05 06:43:39 +13:00 committed by GitHub
parent fef468aad1
commit e310ccac7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 113 deletions

View File

@ -5,32 +5,32 @@
<PropertyGroup Label="Package Versions"> <PropertyGroup Label="Package Versions">
<AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion> <AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion>
<InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-20181031.6</InternalAspNetCoreSdkPackageVersion> <InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-20181031.6</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion> <MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion> <MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>
<MicrosoftAspNetCoreAuthenticationGooglePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationGooglePackageVersion> <MicrosoftAspNetCoreAuthenticationGooglePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationGooglePackageVersion>
<MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion> <MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>
<MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationTwitterPackageVersion> <MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>
<MicrosoftAspNetCoreAuthorizationPackageVersion>3.0.0-a-alpha1-authz-middleware-16949</MicrosoftAspNetCoreAuthorizationPackageVersion> <MicrosoftAspNetCoreAuthorizationPackageVersion>3.0.0-a-alpha1-authz-middleware-16949</MicrosoftAspNetCoreAuthorizationPackageVersion>
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>3.0.0-a-alpha1-authz-middleware-16949</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion> <MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>3.0.0-a-alpha1-authz-middleware-16949</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
<MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion> <MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>
<MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion> <MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion> <MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreDiagnosticsPackageVersion> <MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHostingAbstractionsPackageVersion> <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHostingPackageVersion> <MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHttpAbstractionsPackageVersion> <MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHttpPackageVersion> <MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion> <MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreIdentityPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreIdentityPackageVersion> <MicrosoftAspNetCoreIdentityPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreIdentityPackageVersion>
<MicrosoftAspNetCoreMvcPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreMvcPackageVersion> <MicrosoftAspNetCoreMvcPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreMvcPackageVersion>
<MicrosoftAspNetCoreMvcTestingPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreMvcTestingPackageVersion> <MicrosoftAspNetCoreMvcTestingPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreMvcTestingPackageVersion>
<MicrosoftAspNetCorePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCorePackageVersion> <MicrosoftAspNetCorePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCorePackageVersion>
<MicrosoftAspNetCoreRewritePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreRewritePackageVersion> <MicrosoftAspNetCoreRewritePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreRewritePackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreServerIISIntegrationPackageVersion> <MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion> <MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreServerKestrelPackageVersion> <MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreStaticFilesPackageVersion> <MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreTestHostPackageVersion> <MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview-181106-14</MicrosoftAspNetCoreTestingPackageVersion> <MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview-181106-14</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetIdentityEntityFrameworkPackageVersion>2.2.1</MicrosoftAspNetIdentityEntityFrameworkPackageVersion> <MicrosoftAspNetIdentityEntityFrameworkPackageVersion>2.2.1</MicrosoftAspNetIdentityEntityFrameworkPackageVersion>
<MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion> <MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion>
@ -61,10 +61,10 @@
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion> <MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion> <MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETCoreApp30PackageVersion>3.0.0-preview1-26907-05</MicrosoftNETCoreApp30PackageVersion> <MicrosoftNETCoreApp30PackageVersion>3.0.0-preview1-26907-05</MicrosoftNETCoreApp30PackageVersion>
<MicrosoftNETSdkRazorPackageVersion>3.0.0-alpha1-10717</MicrosoftNETSdkRazorPackageVersion> <MicrosoftNETSdkRazorPackageVersion>3.0.0-alpha1-10772</MicrosoftNETSdkRazorPackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
<MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion> <MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion>
<MicrosoftOwinSecurityInteropPackageVersion>3.0.0-alpha1-10717</MicrosoftOwinSecurityInteropPackageVersion> <MicrosoftOwinSecurityInteropPackageVersion>3.0.0-alpha1-10772</MicrosoftOwinSecurityInteropPackageVersion>
<MoqPackageVersion>4.10.0</MoqPackageVersion> <MoqPackageVersion>4.10.0</MoqPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion> <NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<SystemComponentModelAnnotationsPackageVersion>4.6.0-preview1-26907-04</SystemComponentModelAnnotationsPackageVersion> <SystemComponentModelAnnotationsPackageVersion>4.6.0-preview1-26907-04</SystemComponentModelAnnotationsPackageVersion>

View File

@ -1,12 +1,13 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -49,27 +50,23 @@ namespace StaticFilesAuth
{ {
return false; return false;
} }
var userPath = Path.Combine(usersPath, userName); if (context.Resource is Endpoint endpoint)
if (context.Resource is IFileInfo file)
{ {
var path = Path.GetDirectoryName(file.PhysicalPath); var userPath = Path.Combine(usersPath, userName);
return string.Equals(path, basePath, StringComparison.OrdinalIgnoreCase)
|| string.Equals(path, usersPath, StringComparison.OrdinalIgnoreCase) var directory = endpoint.Metadata.GetMetadata<DirectoryInfo>();
|| string.Equals(path, userPath, StringComparison.OrdinalIgnoreCase) if (directory != null)
|| path.StartsWith(userPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); {
} return string.Equals(directory.FullName, basePath, StringComparison.OrdinalIgnoreCase)
else if (context.Resource is IDirectoryContents dir) || string.Equals(directory.FullName, usersPath, StringComparison.OrdinalIgnoreCase)
{ || string.Equals(directory.FullName, userPath, StringComparison.OrdinalIgnoreCase)
// https://github.com/aspnet/Home/issues/3073 || directory.FullName.StartsWith(userPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase);
// This won't work right if the directory is empty }
var path = Path.GetDirectoryName(dir.First().PhysicalPath);
return string.Equals(path, basePath, StringComparison.OrdinalIgnoreCase) throw new InvalidOperationException($"Missing file system metadata.");
|| string.Equals(path, usersPath, StringComparison.OrdinalIgnoreCase)
|| string.Equals(path, userPath, StringComparison.OrdinalIgnoreCase)
|| path.StartsWith(userPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase);
} }
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 => 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 => 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 => app.UseMvc(routes =>
@ -114,81 +114,51 @@ namespace StaticFilesAuth
}); });
} }
// Blanket authorization, any authenticated user is allowed access to these resources. private void SetupFileServer(IApplicationBuilder builder, IFileProvider files)
private static void MapAuthenticatedFiles(IApplicationBuilder branch, PhysicalFileProvider files)
{ {
branch.Use(async (context, next) => builder.UseFileServer(new FileServerOptions()
{
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()
{ {
EnableDirectoryBrowsing = true, EnableDirectoryBrowsing = true,
FileProvider = files FileProvider = files
}); });
} }
// Policy based authorization, requests must meet the policy criteria to be get access to the resources. private static void SetFileEndpoint(HttpContext context, PhysicalFileProvider files, string policy)
private static void MapImperativeFiles(IAuthorizationService authorizationService, IApplicationBuilder branch, PhysicalFileProvider files)
{ {
branch.Use(async (context, next) => var fileSystemPath = GetFileSystemPath(files, context.Request.Path);
if (fileSystemPath != null)
{ {
var fileInfo = files.GetFileInfo(context.Request.Path); var metadata = new List<object>();
AuthorizationResult result = null; metadata.Add(new DirectoryInfo(Path.GetDirectoryName(fileSystemPath)));
if (fileInfo.Exists) metadata.Add(new AuthorizeAttribute(policy));
{
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;
}
}
if (!result.Succeeded) var endpoint = new Endpoint(
{ c => throw new InvalidOperationException("Static file middleware should return file request."),
if (!context.User.Identity.IsAuthenticated) new EndpointMetadataCollection(metadata),
{ context.Request.Path);
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;
}
await next(); context.SetEndpoint(endpoint);
}); }
branch.UseFileServer(new FileServerOptions() }
private static string GetFileSystemPath(PhysicalFileProvider files, string path)
{
var fileInfo = files.GetFileInfo(path);
if (fileInfo.Exists)
{ {
EnableDirectoryBrowsing = true, return Path.Join(files.Root, path);
FileProvider = files }
}); else
{
// https://github.com/aspnet/Home/issues/2537
var dir = files.GetDirectoryContents(path);
if (dir.Exists)
{
return Path.Join(files.Root, path);
}
}
return null;
} }
} }
} }

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>