Вернуть JWT после аутентификации через Open Id

Я разрабатываю основной веб-API ASP.NET, в котором пользователь входит в систему через Steam.

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = SteamAuthenticationDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddSteam(options =>
        {
            options.Events.OnAuthenticated = ctx => // Create user
        });

    // ...
}

На данный момент я использую файл cookie, и аутентификация и авторизация работают нормально. Но я хотел бы использовать JWT. Если я просто заменю AddCookie на AddJwtBearer, я получу следующее исключение: The authentication handler registered for scheme 'Bearer' is 'JwtBearerHandler' which cannot be used for SignInAsync.

В этом проблеме github говорится, что я бы нужен сервер OpenID Connect, но я не понимаю, почему, потому что, если бы я хотел написать логику JWT самостоятельно, я мог бы сгенерировать токен в обратном вызове open id и вернуть его пользователю. Или я что-то упускаю?


person Greg    schedule 14.01.2020    source источник


Ответы (1)


См. комментарий @KévinChalet о проблеме безопасности с приведенным ниже кодом.

Вызовите HandleResponse в SteamAuthenticationOptions.Events.OnTicketReceived, чтобы он не вызывал SignInAsync и имел возможность самостоятельно выполнить перенаправление для присоединения к jwt.

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options => // ...)
        .AddSteam(options =>
        {
            options.Events.OnAuthenticated = ctx =>
            {
                var res = ctx.User[SteamAuthenticationConstants.Parameters.Response];
                var players = res[SteamAuthenticationConstants.Parameters.Players];
                var player = players.First.ToObject<SteamPlayer>();
                // Create user and generate jwt, then
                ctx.Request.HttpContext.Items["jwt"] = jwt;
            });

            options.Events.OnTicketReceived = ctx =>
            {
                ctx.HandleResponse();

                var jwt = ctx.Request.HttpContext.Items["jwt"] as string;
                ctx.Response.Redirect(QueryHelpers.AddQueryString(ctx.ReturnUri, "token", jwt));
                return Task.CompletedTask;
            };
        });

    // ...
}

Когда аутентификация проходит успешно после вызова Steam, генерируется jwt и пользователь перенаправляется на {ReturnUri}?token={jwt}.

person Greg    schedule 28.01.2020
comment
Я бы не рекомендовал этот подход по упомянутой причине здесь. - person Kévin Chalet; 16.02.2020