2016-10-05 3 views
1

Я создал свое собственное промежуточное программное обеспечение для аутентификации в asp. чистый основной проект, и зарегистрировал его, как показано ниже:Условно использовать специальное промежуточное ПО

public class MyAuthenticationMidleware 
{ 
    private readonly RequestDelegate _next; 

    public ConnectAuthenticationMidleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     if (!UserIsAuthenticated()) 
     { 
      context.Response.StatusCode = 401; 
      return; 
     } 
     ... 
     await _next.Invoke(context); 
    } 
} 

public static class MyAuthenticationMidlewareExtensions 
{ 
    public static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder builder) 
    { 
     return builder.UseMiddleware<MyAuthenticationMidleware>(); 
    } 
} 

В Startup:

public void Configure(...) 
    { 
     app.UseStaticFiles(); 
     app.UseMyAuthentication(); 
     app.UseMvc(); 
    } 

Это работает правильно - аутентификация промежуточного слоя выполняется для каждого запроса. Если пользователь не аутентифицирован, возвращается 401. В противном случае вызывается конкретное действие mvc.

Что я пытался сделать, это предотвратить запуск промежуточного программного обеспечения аутентификации для определенных действий. Я использовал MapWhen метод, чтобы создать другой метод расширения и использовать его следующим образом:

public static class MyAuthenticationMidlewareExtensions 
{ 
    public static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder builder) 
    { 
     return builder.UseMiddleware<MyAuthenticationMidleware>(); 
    } 

    public static IApplicationBuilder UseMyAuthenticationWhen(this IApplicationBuilder builder, Func<HttpContext, bool> predicate) 
    { 
     return builder.MapWhen(predicate, applicationBuilder => applicationBuilder.UseMyAuthentication()); 
    } 
} 

public void Configure(...) 
{ 
    app.UseStaticFiles(); 
    app.UseMyAuthenticationWhen(context => context.Request.Path != "xyz"); 
    app.UseMvc(); 
} 

К сожалению, это не работает, как ожидалось. Среднее программное обеспечение вызывается только тогда, когда путь отличается от «xyz», но кажется, что он замыкает всю цепочку - никаких специальных действий или фильтров mvc не вызывается.

Возможно, мое понимание MapWhen было неправильным. Есть ли способ получить результат, который я хочу?

ответ

0

MapWhen Используется для разделения промежуточного конвейера. Если вы хотите использовать mvc для расширенного конвейера, вам нужно добавить отдельно. Таким образом, вы должны использовать .UseMvc(); в метод расширения, как показано ниже:

public static IApplicationBuilder UseMyAuthenticationWhen(this IApplicationBuilder builder, Func<HttpContext, bool> predicate) 
{ 
    return builder.MapWhen(predicate, applicationBuilder => 
    { 
     applicationBuilder.UseMyAuthentication(); 
     applicationBuilder.UseMvc(); 
    }); 
} 

Однако я не пошел бы с пути. Для промежуточного программного обеспечения для проверки подлинности я бы использовал свое собственное промежуточное программное обеспечение, например Simple token based authentication/authorization in asp.net core for Mongodb datastore, и использовал атрибут Authorize для авторизации mvc-действий.

3

MapWhen создает новую ветвь трубопровода, когда входящий в комплект поставки предикат истинен, и что филиал делает не воссоединиться с основной ветвью, где у вас есть UseMvc().

Вы можете изменить свой метод расширения, чтобы использовать UseWhen вместо MapWhen. UseWhenrejoins with the main pipeline, чтобы ваш UseMvc() по-прежнему вызывался.

Примечание: Хотя приведенные выше ссылки ссылка Сеть САШ-вно, метод UseWhen расширение в настоящее время является частью Microsoft.AspNetCore.Http.Abstractions.

Это позволяет сохранить UseMvc() явное в методе Configure вместо спрятан в вашем методе расширения аутентификации, где он на самом деле не имеет никакого бизнеса, благополучия.

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