Как я могу ограничить доступ к статическому файлу для конкретного зарегистрированного пользователя? - PullRequest
0 голосов
/ 27 октября 2019

Есть ли способ программно предоставить определенному пользователю доступ к определенному статическому файлу?

Пример: пользователь загружает /wwwroot/files/users/2137/document.pdf. Теперь этот файл должен не быть доступным, перейдя к www.domain.com/files/users/2137/document.pdf. Только этот пользователь или другие пользователи, которым предоставлен доступ, могут получить к нему доступ через бэкэнд-систему.

1 Ответ

1 голос
/ 28 октября 2019

Вы можете использовать Middleware + Authorization Policy для достижения этой цели:

  1. Определить политику, в которой пользователь может получить доступ только к своим собственным ресурсам.
  2. Вызвать IAuthorizationService в промежуточном программном обеспечении, которое проверяет политику перед переходом в промежуточное программное обеспечение StaticFiles.

Например, вот AuthorizationHandler, который выполняет это требование:

public class RestrictStaticFilesRequirement: AuthorizationHandler<RestrictStaticFilesRequirement>,IAuthorizationRequirement 
{
    public const string DefaultPolicyName = "Access-His-Own-Static-Files";
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RestrictStaticFilesRequirement requirement)
    {
        var user = context.User;                      // current User Principal
        var userName = context.Resource as string;    // current userName
        // custom this requirement as you like
        if(user != null && !string.IsNullOrEmpty(userName) && user.HasClaim(ClaimTypes.NameIdentifier, userName)) {
            context.Succeed(requirement);
        } else {
            context.Fail();
        }
        return Task.CompletedTask;
    }
}

Зарегистрируйте это требование как Policy:

services.AddAuthorization(opts =>{
    opts.AddPolicy(RestrictStaticFilesRequirement.DefaultPolicyName,pb => pb.AddRequirements(new RestrictStaticFilesRequirement()) );
});

Наконец, проверьте политику с помощью IAuthorizationService и определите, разрешен ли текущий запрос:

app.UseAuthentication();

app.UseWhen( ctx => ctx.Request.Path.StartsWithSegments("/files/users"), appBuilder =>{
    appBuilder.Use(async (context, next) => {
        // get the userId in current Path : "/files/users/{userId}/...."
        var userId = context.Request.Path.Value.Substring("/files/users/".Length)
            .Split('/')
            .FirstOrDefault();
        if(string.IsNullOrEmpty(userId)){
            await next();    // current URL is not for static files
            return;
        }
        var auth= context.RequestServices.GetRequiredService<IAuthorizationService>();
        var result = await auth.AuthorizeAsync( context.User, userId ,RestrictStaticFilesRequirement.DefaultPolicyName);
        if(!result.Succeeded){
            context.Response.StatusCode= 403;
            return;
        }
        await next();
    });
});
app.UseStaticFiles();

// ... other middlewares
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...