Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RestSharp with JWT-authentication doesn't work

This is the page where I "learned" how to do it: https://stormpath.com/blog/token-authentication-asp-net-core

But for me this is not working (doesn't work with Fiddler, too) There is this controller for my 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);
    }
}

and there's my wrapper for RestSharp to get all applicationusers:

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;
}

From my web-client application I want to login with JWT (Token-Authentication) what works. After login I get e.g. this access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJURVNUIiwianRpIjoiZTBjYjE0NjgtYzBmOS00ZTM4LTg4ZjgtMGM4ZjNmYjMyNjZmIiwiaWF0IjoxNDcwOTUwMTA0LCJuYmYiOjE0NzA5NTAxMDQsImV4cCI6MTQ3MDk1MDQwNCwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.a9_JK2SG3vzc6NSOB0mZXqHlM9UAEXUHHrrijAQUsX0

without the Authorize-attribute I get the ApplicationUser, but when setting the Attribute, the result is null (since the web-api is not getting called)

the wrapper-call looks like this:

//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);

and here userAfterLogin is null.

I'm trying to get the login since two weeks but I still don't get it right..

Any idea what I'm doing wrong? Maybe a wrong request-header-value for authorization?

Update

this is my Startup.Configure where I configured to use the 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?}");
    });
}
like image 244
Matthias Burger Avatar asked Aug 11 '16 21:08

Matthias Burger


People also ask

How does authentication work with JWT?

To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.

Can JWT be used for authentication?

JWTs can be used as an authentication mechanism that does not require a database. The server can avoid using a database because the data store in the JWT sent to the client is safe.

How do I request RestSharp?

To make a POST request using RestSharp, you can use the following code: RestRequest request = new RestRequest("Default", Method. POST);


1 Answers

If you recive authorizacion error or using postman you realize that you are being asked to redirect to login just decorate your class with:

[Authorize(AuthenticationSchemes = "Bearer")]

By default .Net uses cookie based auth, with that annotation you swicht to token based one

like image 193
jeprato Avatar answered Oct 20 '22 01:10

jeprato