Aspnetcore Bearer auth: использовать пользователя внутри промежуточного программного обеспечения - PullRequest
0 голосов
/ 31 декабря 2018

Я использую куки и аутентификацию на предъявителя в своем приложении.Но у меня странное поведение, которое я не могу объяснить.

У меня есть пользовательское промежуточное ПО, в которое я добавляю некоторые необходимые данные в Context.Items Все хорошо, но в этом промежуточном ПО пользователь пуст, если его носитель, но все в порядкекогда его куки.

   services
                .AddAuthorization(options =>
                {
                    options.DefaultPolicy = new AuthorizationPolicyBuilder()
                        .AddAuthenticationSchemes(OAuthValidationDefaults.AuthenticationScheme,
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            "Identity.Application")
                        .RequireAuthenticatedUser()
                        .Build();
                });
            //CookieAuthenticationDefaults.AuthenticationScheme
            services.AddAuthentication()
                .AddExternalAuthProviders(Configuration)
                .AddFlymarkOpenIdConnectServer()
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.LoginPath = "/Identity/Account/LogIn";
                    options.SlidingExpiration = true;
                    options.Events.OnRedirectToLogin = OnRedirectToLogin;
                })
                .AddOAuthValidation(OAuthValidationDefaults.AuthenticationScheme,
                    o=>o.Events.OnCreateTicket = OnCreateTicket);
            services.ConfigureApplicationCookie(config =>
            {
                config.Events = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = OnRedirectToLogin
                };
            });

Временно я использую на CreateTicket, которые решают мою проблему

   private async Task OnCreateTicket(CreateTicketContext arg)
        {
            if (arg.HttpContext.Items[FlymarkWeb.CurrentUserKey] == null && arg.Identity.IsAuthenticated)
            {
                var db= (FlymarkContext) arg.HttpContext.RequestServices.GetService(typeof(FlymarkContext));
                arg.HttpContext.Items[FlymarkWeb.CurrentUserKey] =
                    await db.Users.FirstOrDefaultAsync(u => u.Id == arg.Identity.GetUserId());
            }
        }

И промежуточное программное обеспечение

  public async Task Invoke(HttpContext httpContext, FlymarkContext context, DomainService _sourceDomainService)
        {
            if (httpContext.Items[FlymarkWeb.CurrentUserKey] == null)
            {
                httpContext.Items[FlymarkWeb.CurrentUserKey] = httpContext.User.Identity.IsAuthenticated
                    ? await context.Users.FirstOrDefaultAsync(u => u.Id == httpContext.User.GetUserId())
                    : null;
            }
....
}

Так что мой вопрос, почему куки иааут разные?Почему, если это cookie, я могу получить доступ к пользователю в промежуточном программном обеспечении, и если его нет, я не могу?

1 Ответ

0 голосов
/ 31 декабря 2018

Это потому, что ASP.NET Core Identity регистрируется в качестве обработчика схемы аутентификации по умолчанию при вызове services.AddIdentity().

При получении запроса промежуточное программное обеспечение, стоящее за app.UseAuthentication(), будет автоматическивызовите обработчик аутентификации cookie, зарегистрированный Identity, и заполните HttpContext.User полученным ClaimsPrincipal, извлеченным из cookie аутентификации.

С токенами носителя этого не происходит, потому что обработчик проверки OAuth не регистрируетсясам как обработчик аутентификации по умолчанию (это то, что вы должны сделать вручную и явно в 2.0).

Чтобы настроить его как обработчик по умолчанию, вы можете сделать это:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = OAuthValidationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OAuthValidationDefaults.AuthenticationScheme;
});

В качестве альтернативы,Вы можете непосредственно выполнить операцию аутентификации самостоятельно, вместо того, чтобы полагаться на HttpContext.User.Например:

public async Task Invoke(HttpContext httpContext, FlymarkContext context, DomainService _sourceDomainService)
{
    if (httpContext.Items[FlymarkWeb.CurrentUserKey] == null)
    {
        var principal = (await httpContext.AuthenticateAsync(OAuthValidationDefaults.AuthenticationScheme))?.Principal;

        httpContext.Items[FlymarkWeb.CurrentUserKey] = principal?.Identity != null && principal.Identity.IsAuthenticated
            ? await context.Users.FirstOrDefaultAsync(u => u.Id == principal.GetUserId())
            : null;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...