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">
<AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion>
<InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-20181031.6</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>
<MicrosoftAspNetCoreAuthenticationGooglePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationGooglePackageVersion>
<MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>
<MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>
<MicrosoftAspNetCoreAuthenticationGooglePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationGooglePackageVersion>
<MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>
<MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>
<MicrosoftAspNetCoreAuthorizationPackageVersion>3.0.0-a-alpha1-authz-middleware-16949</MicrosoftAspNetCoreAuthorizationPackageVersion>
<MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>3.0.0-a-alpha1-authz-middleware-16949</MicrosoftAspNetCoreAuthorizationPolicyPackageVersion>
<MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>
<MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreIdentityPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreIdentityPackageVersion>
<MicrosoftAspNetCoreMvcPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreMvcPackageVersion>
<MicrosoftAspNetCoreMvcTestingPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreMvcTestingPackageVersion>
<MicrosoftAspNetCorePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCorePackageVersion>
<MicrosoftAspNetCoreRewritePackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreRewritePackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10717</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>
<MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreIdentityPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreIdentityPackageVersion>
<MicrosoftAspNetCoreMvcPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreMvcPackageVersion>
<MicrosoftAspNetCoreMvcTestingPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreMvcTestingPackageVersion>
<MicrosoftAspNetCorePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCorePackageVersion>
<MicrosoftAspNetCoreRewritePackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreRewritePackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10772</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview-181106-14</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetIdentityEntityFrameworkPackageVersion>2.2.1</MicrosoftAspNetIdentityEntityFrameworkPackageVersion>
<MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion>
@ -61,10 +61,10 @@
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
<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>
<MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion>
<MicrosoftOwinSecurityInteropPackageVersion>3.0.0-alpha1-10717</MicrosoftOwinSecurityInteropPackageVersion>
<MicrosoftOwinSecurityInteropPackageVersion>3.0.0-alpha1-10772</MicrosoftOwinSecurityInteropPackageVersion>
<MoqPackageVersion>4.10.0</MoqPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<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.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<DirectoryInfo>();
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<object>();
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;
}
}
}

View File

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