簡體   English   中英

帶有JWT身份驗證的RestSharp不起作用

[英]RestSharp with JWT-authentication doesn't work

這是我“學習”如何做的頁面: https : //stormpath.com/blog/token-authentication-asp-net-core

但是對我來說這不起作用(也不適用於Fiddler)我的ApplicationUser-model有這個控制器:

[Authorize] //works when it's not set, doesn't work when it's 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;
}

我想從Web客戶端應用程序中使用JWT(令牌身份驗證)登錄。 登錄后,我得到這個如的access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0

沒有Authorize -attribute,我得到了ApplicationUser,但是在設置Attribute時,結果為null(因為未調用web-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?}");
    });
}

如果您收到授權錯誤或使用郵遞員,您將意識到您被要求重定向到登錄名,只需使用以下命令裝飾您的班級:

[Authorize(AuthenticationSchemes = "Bearer")]

默認情況下,.Net使用基於cookie的身份驗證,帶有該注釋的您將粘貼到基於令牌的令牌中

因此,您正在使用2個中間件進行身份驗證。 一個由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或JwtBearer的請求,它們中的任何一個都將返回Unauthorized。

對於您要尋找的解決方案,您需要在現有的cookie和令牌的基礎上創建一個中間件,以根據是否存在授權標頭將請求路由到其中一個。

在Fiddler中,您將看到是否將您重定向到登錄頁面(它將報告2個結果,其中一個為302(重定向),然后為404)-是這樣嗎?

您已激活DebugLogger,因此請嘗試AddDebug(LogLevel.Trace)並查看“調試”輸出窗口,這對於分析哪些身份驗證步驟失敗非常有幫助。 它還顯示身份驗證是否失敗或授權,以及是否具有有效的令牌等。因此,它指出了查找問題的方向。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM