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;
} }
if (context.Resource is Endpoint endpoint)
{
var userPath = Path.Combine(usersPath, userName); var userPath = Path.Combine(usersPath, userName);
if (context.Resource is IFileInfo file)
var directory = endpoint.Metadata.GetMetadata<DirectoryInfo>();
if (directory != null)
{ {
var path = Path.GetDirectoryName(file.PhysicalPath); return string.Equals(directory.FullName, basePath, StringComparison.OrdinalIgnoreCase)
return string.Equals(path, basePath, StringComparison.OrdinalIgnoreCase) || string.Equals(directory.FullName, usersPath, StringComparison.OrdinalIgnoreCase)
|| string.Equals(path, usersPath, StringComparison.OrdinalIgnoreCase) || string.Equals(directory.FullName, userPath, StringComparison.OrdinalIgnoreCase)
|| string.Equals(path, userPath, StringComparison.OrdinalIgnoreCase) || directory.FullName.StartsWith(userPath + Path.DirectorySeparatorChar, 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);
} }
throw new NotImplementedException($"Unknown resource type '{context.Resource.GetType()}'"); throw new InvalidOperationException($"Missing file system metadata.");
}
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)));
metadata.Add(new AuthorizeAttribute(policy));
var endpoint = new Endpoint(
c => throw new InvalidOperationException("Static file middleware should return file request."),
new EndpointMetadataCollection(metadata),
context.Request.Path);
context.SetEndpoint(endpoint);
}
}
private static string GetFileSystemPath(PhysicalFileProvider files, string path)
{
var fileInfo = files.GetFileInfo(path);
if (fileInfo.Exists) if (fileInfo.Exists)
{ {
result = await authorizationService.AuthorizeAsync(context.User, fileInfo, "files"); return Path.Join(files.Root, path);
} }
else else
{ {
// https://github.com/aspnet/Home/issues/2537 // https://github.com/aspnet/Home/issues/2537
var dir = files.GetDirectoryContents(context.Request.Path); var dir = files.GetDirectoryContents(path);
if (dir.Exists) if (dir.Exists)
{ {
result = await authorizationService.AuthorizeAsync(context.User, dir, "files"); return Path.Join(files.Root, path);
}
else
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
return;
} }
} }
if (!result.Succeeded) return null;
{
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;
}
await next();
});
branch.UseFileServer(new FileServerOptions()
{
EnableDirectoryBrowsing = true,
FileProvider = files
});
} }
} }
} }

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>