2017-01-08 40 views
3

Я хочу создать собственный атрибут авторизации для проверки пути и URL-адреса.Как создать настраиваемый атрибут авторизации для проверки роли и URL-адреса в Asp.Net Core?

Я нашел способ сделать это в ядре Asp.Net с использованием авторизации на основе политик, но я попытался реализовать его, но я не могу получить HttpContext с входящим URL.

AuthorizationHandlerContext не имеет доступа к HttpContext вероятным.

Как я могу получить текущий HttpContext с URL-адресом? Можно ли это сделать или по-другому?

Я попробовал этот код для создания пользовательской политики:

public class RoleUrlValidationHandler : AuthorizationHandler<RoleUrlValidationRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleUrlValidationRequirement requirement) 
    {   
     var path = //Here I need get current url path for example - /api/posts/4545411 
     var pathPart = path.Split('/'); 
     var clientId = pathPart[3]; 

     if (context.User.IsInRole(clientId)) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 
} 

Я хочу создать следующее:

[Authorize(Policy="RoleUrlValidation")] //Get ClientId from Url and check User's roles 
public class PostsController : Controller 
{ 
    public ActionResult Get() 
    { 
    } 
} 
+0

Frist Вы не должны реализовывать собственные атрибуты Autzorize. Правильный подход с Политикой. Во-вторых, вы можете использовать DI внутри обработчиков – Tseng

+0

@Tseng Извините, что вы имеете в виду «не должны реализовывать собственные атрибуты Autzorize». и почему? –

+1

@ b.ben: команда ASP.NET Core сделала определенные методы по методу 'AuthorizeAttribute' не виртуальными (или удалила их), означает, что вы больше не можете их переопределять (например, для работы с устаревшим ASP.NET). Они представили авторизацию на основе политики в качестве замены, поскольку ее более гибкие и более легкие для третьих сторон добавление новых политик, см. [Этот ответ] (https://stackoverflow.com/a/31465227/455493) от blowdart, разработчик, ответственный за ASP.NET Core security – Tseng

ответ

5

подход политика является правильным. Только бит, который вы пропустили, заключается в том, что вы можете использовать Injection Dependency в обработчиках.

public class RoleUrlValidationHandler : AuthorizationHandler<RoleUrlValidationRequirement> 
{ 
    private readonly IHttpContextAccessor contextAccessor; 
    public class RoleUrlValidationHandler(IHttpContextAccessor contextAccessor) 
    { 
     this.contextAccessor = contextAccessor; 
    } 

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleUrlValidationRequirement requirement) 
    { 
     var httpContext = contextAccessor.HttpContext; 
     var path = httpContext.Request.Path; 
     var pathPart = path.Split('/'); 
     var clientId = pathPart[3]; 

     if (context.User.IsInRole(clientId)) 
     { 
      context.Succeed(requirement); 
     } 

     return Task.CompletedTask; 
    } 
} 

Вы можете также зарегистрировать IHttpContextAccessor как его не зарегистрирован по умолчанию.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 

Дополнительные биты:

Рассмотрите возможность использования var routeData = httpContext.GetRouteData() вместо использования path.Split('/') для чтения значений из него, так что вы можете легко считывать значения параметров с маршрута.

+0

Это выглядит потрясающе. Я попробую. Да, вы правы, я пропустил возможность DI для этого. :-) Благодаря. – Jenan

+0

Вы имеете в виду httpContext.GetRouteData(); вероятным? – Jenan

+0

Да, правильно. На самом деле это не было связано с приведенным выше кодом, просто обобщенная форма. Но исправит это, чтобы избежать путаницы – Tseng

Смежные вопросы