Подтвердить что ты не робот

RestSharp с JWT-аутентификацией не работает

Это страница, где я "научился", как это сделать: https://stormpath.com/blog/token-authentication-asp-net-core

Но для меня это не работает (тоже не работает с Fiddler) Этот контроллер для моей модели ApplicationUser:

[Authorize] //works when it not set, doesn't work when it set
[Route("api/[controller]")]
public class ApplicationUserController : Controller
{
    private IRepository<ApplicationUser> _applicationUserRepository;

    public ApplicationUserController(IRepository<ApplicationUser> applicationUserRepository)
    {
        _applicationUserRepository = applicationUserRepository;
    }

    [HttpGet("{id}")]
    public ApplicationUser Get(int id)
    {
        return _applicationUserRepository.Get(id);
    }
}

и там моя обложка для RestSharp для получения всех приложений:

public Task<T> GetResponseContentAsync<T>(string resource, int id) where T : new()
{
    RestRequest request = new RestRequest($"{resource}/{{id}}", Method.GET);
    request.AddUrlSegment("id", id);
    if (!AuthenticationToken.IsNullOrEmpty(true))
    {
        request.AddHeader("Authorization", string.Format("Bearer {0}", AuthenticationToken));
        _client.Authenticator = new JwtAuthenticator(AuthenticationToken);
        _client.Authenticator.Authenticate(_client, request);
    }

    TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
    _client.ExecuteAsync<T>(request, response =>
    {
        tcs.SetResult(response.Data);
    });
    return tcs.Task;
}

Из моего веб-клиентского приложения я хочу войти в систему с JWT (Token-Authentication), что работает. После входа в систему я получаю, например, this access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0

без атрибута Authorize Я получаю ApplicationUser, но при настройке атрибута результат равен null (поскольку веб-api не получает вызов)

оберточный вызов выглядит следующим образом:

//this works, token-value is set
string token = new RepositoryCall("http://localhost:54008/").Login("token", "TEST", "TEST123");

string accessToken = JsonConvert.DeserializeObject<Dictionary<string, string>>(token)["access_token"];
ViewData["Result"] = accessToken;

ApplicationUser userAfterLogin = await new RepositoryCall("http://localhost:54008/api") 
    { AuthenticationToken = accessToken }
    .GetResponseContentAsync<ApplicationUser>("ApplicationUser", 2);

и здесь userAfterLogin имеет значение null.

Я пытаюсь получить логин с двух недель, но я все равно не понимаю.

Любая идея, что я делаю неправильно? Возможно, неправильное значение заголовка запроса для авторизации?

Обновление

это мой Startup.Configure, где я настроен для использования Bearer/JWT:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();

    app.UseIdentity();
    var secretKey = "mysupersecret_secretkey!123";
    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));

    // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
    var options = new TokenProviderOptions
    {
        Audience = "ExampleAudience",
        Issuer = "ExampleIssuer",
        SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
    };


    var tokenValidationParameters = new TokenValidationParameters
    {
        // The signing key must match!
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingKey,

        // Validate the JWT Issuer (iss) claim
        ValidateIssuer = true,
        ValidIssuer = "ExampleIssuer",

        // Validate the JWT Audience (aud) claim
        ValidateAudience = true,
        ValidAudience = "ExampleAudience",

        // Validate the token expiry
        ValidateLifetime = true,

        // If you want to allow a certain amount of clock drift, set that here:
        ClockSkew = TimeSpan.Zero
    };


    app.UseJwtBearerAuthentication(new JwtBearerOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        TokenValidationParameters = tokenValidationParameters
    });

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        AuthenticationScheme = "Cookie",
        CookieName = "access_token",
        TicketDataFormat = new CustomJwtDataFormat(
            SecurityAlgorithms.HmacSha256,
            tokenValidationParameters)
    });

    app.UseMiddleware<TokenProviderMiddleware>(Options.Create(options));
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}
4b9b3361

Ответ 1

Итак, вы используете 2 middlewares для идентификации. Один предоставляется идентификатором asp.net(основанный на файлах cookie) и другой маркер. Теперь оба промежуточного слоя используют один и тот же атрибут для обрабатывая запрос [Авторизовать]. Более точно посмотрите на код здесь

https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs

для JWTBearer

и

https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs

для Cookie

Поскольку оба они активируются в конвейере промежуточного программного обеспечения, у принципала будут данные, когда вы отправляете токен аутентификации или файл cookie.

Но поскольку оба они активны, любой из них будет возвращать Unauthorized для запроса, у которого нет cookie или JwtBearer.

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

Ответ 2

В Fiddler вы увидите, что если вы перенаправлены на страницу входа в систему (он будет сообщать 2 результата, один с 302 (перенаправление), а затем 404 - это случай?

У вас активирован DebugLogger, поэтому попробуйте AddDebug (LogLevel.Trace) и просмотрите окно вывода Debug, очень полезно при анализе того, какие из шагов аутентификации терпят неудачу. Он также показывает, что аутентификация завершается с ошибкой или авторизация, а также имеет действительный токен и т.д. Таким образом, он указывает на направление поиска проблем.