Как обойти промежуточное ПО аутентификации, когда оно не нужно в ASP.NET Core - PullRequest
0 голосов
/ 10 июня 2019

У меня есть следующий обработчик аутентификации:

public class CustomAuthenticationHandler : AuthenticationHandler<CustomAuthenticationSchemeOptions>
{
    public CustomAuthenticationHandler (
        IOptionsMonitor<CustomAuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var data = await GetDataFromDatabase(); //heavy load
        if(data.IsAuth)
        {
          var identity = new ClaimsIdentity(claims, Scheme.Name);
          var principal = new ClaimsPrincipal(identity);
          var ticket = new AuthenticationTicket(principal, Scheme.Name);

          return Task.FromResult(AuthenticateResult.Success(ticket));
       }
       return Task.FromResult(AuthenticateResult.Failed("Not authenticated"));
    }
}

Я регистрирую его так в ConfigureServices:

services.AddAuthentication(options =>
    {
      options.DefaultAuthenticateScheme = CustomAuthenticationSchemeOptions.SchemeName;
      options.DefaultChallengeScheme = CustomAuthenticationSchemeOptions.SchemeName;
    })
    .AddScheme<CustomAuthenticationSchemeOptions, CustomAuthenticationHandler>(CustomAuthenticationSchemeOptions.SchemeName, null);

Затем я использую его так в Configure:

app.UseAuthentication();

У меня есть несколько Controllers с несколькими Actions.Некоторые из этих действий должны быть доступны только после аутентификации.

Я думал, что если я использую атрибут [Authorize], я требую, чтобы только аутентифицированные пользователи имели доступ к oot, поэтому мое промежуточное программное обеспечение будет вызываться с этим запросом ипротокол аутентификации выполняется (я думаю, это было бы очень элегантное и эффективное решение).

public class RegisterController: ControllerBase
{
   public async Task<AsyncResult<int>>> Reg(string name)
   {
     //...
   }
}

[Authorize]
public class DataController: Controller
{
   public async Task<AsyncResult<Data>>> GetData(int dataId)
   {
     //...
   }
}

Кажется, что я ошибся, поскольку каждое промежуточное ПО вызывается каждый раз когда приходит запрос .

Поэтому, если я не хочу выполнять поиск в базе данных после каждого запроса Action, я должен фильтровать, когда используется промежуточное программное обеспечение.

Я вижу какое-то решение на основе условий для использования app.UseWhen и протестируйте путь запроса и другие громоздкие способы.

Есть ли более элегантный и эффективный способ?Поскольку у меня много действий, я не могу создать проверку пути для каждого из них.

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Я думаю, что вы путаете аутентификацию и авторизацию. Из документов ,

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

То, что вы создали, является обработчиком аутентификации. Аутентификация выполняется независимо от того, существует ли атрибут авторизации, поскольку целью аутентификации является не только авторизация. Это также идентификация. Вы должны настроить аутентификацию таким образом, чтобы не вызывать нагрузку на дб при каждом запросе, например, путем выдачи веб-токена JSON или файла cookie приложения в выбранной конечной точке, такой как /account/login. После того, как вы настроите аутентификацию таким образом, вы можете настроить пользовательский обработчик авторизации или атрибут авторизации, который проверяет утверждения через HttpContext.User.Claims, чтобы увидеть, авторизован ли пользователь для доступа к ресурсу (и даже выполнить легкую проверку). активность БД по этому вопросу, например поиск ролей пользователей.)

В этом руководстве описывается , как настроить обработчики авторизации , но вы можете начать с чтения authorization first.

1 голос
/ 10 июня 2019

Если вы добавите авторизацию в ваш конвейер промежуточного программного обеспечения, это будет по умолчанию для всех вызовов вашего API. Поэтому все вызовы будут действовать так, как будто к ним применен атрибут [Authorize].

Обычно это желательно, так как по умолчанию ваше приложение защищено, и вы не можете случайно забыть атрибут [Authorize]. Я бы порекомендовал сохранить это так и просто добавить тег [AllowAnnonymous] к контроллерам / действиям, которые вы хотите сделать общедоступными.

Если вы хотите быть явным в любое время, просто удалите app.UseAuthentication();. Вы по-прежнему сможете использовать [Authorize], который будет запускать ваше промежуточное ПО, поскольку вы добавили службу для использования. Но он не будет автоматически запускаться для всех вызовов.

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

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

services.AddAuthorization(options =>
{
    var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
        CustomAuthenticationSchemeOptions.SchemeName);

    defaultAuthorizationPolicyBuilder = 
        defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();

    options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});

Чтобы расширить сказанное другими, существуют тонкие различия между аутентификацией и аутентификацией. Аутентификация говорит, кто пользователь, авторизация говорит, что ему разрешено делать. Все вышеперечисленное просто говорит о том, что ... при условии, что я знаю, кто является пользователем (авторизован), ему разрешено использовать мои действия (авторизован). Таким образом, ваша политика авторизации по умолчанию эффективна, если пользователь успешно аутентифицирован.

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