Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

aspnet core jwt token as get param

I'm working an an aspnet core 2 web api project, which main consumer is a vue web app.

Api uses jwt tokens as authentication method, and everything works fine.

Now i've put up all code to manage image storage and retrieval to/from database, but i have a problem in getting images out of db.

All routes (except login) is behind authentication, so to retrieve an image i have pass token within request header (as usually)

This prevents me from using image source tag to actually display the image, as in

<img src="/api/images/27" />

instead, i have to write some javascript code to request the image and place the content in the image tag, something like

// extracted from vue code (not my code, i'm the backend guy)
getImage() {
    this.$http.get('api/images/27', {headers: {'Authorization': 'Bearer ' + this.token},responseType: 'blob'})
    .then(response => {
        return response.blob()
    }).then(blob => { 
        this.photoUrl = URL.createObjectURL(blob)
    })
}

This works, but it's somehow an unnecessary complication.

I see in AspNet Core Identity that

Alternatively, you could obtain the token from somewhere else, such as a different header, or even a cookie. In that case, the handler will use the provided token for all further processing

(extracted from this article from Andre Lock blog) as you can also see checking aspnet core security code, where it says

Give application opportunity to find from a different location, adjust, or reject token

But i can't find any example on how to use this functionality and pass a custom token.

So, my question is: does anyone have any clue on how to pass a custom token (maybe read from a get parameter) to identity provider (maybe even only for some defined routes) ?


Thanks to serpent5 for his correct answer.

If anyone is interested, complete code for reading token from url param and passing it to validation is the following

service.AddAuthentication(...)
    .AddJwtBearer(options =>
        // ...
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = ctx =>
            {
                // replace "token" with whatever your param name is
                if (ctx.Request.Method.Equals("GET") && ctx.Request.Query.ContainsKey("token"))
                    ctx.Token = ctx.Request.Query["token"];
                return Task.CompletedTask;
            }
        };
    });
like image 829
p.desterlich Avatar asked Nov 28 '17 13:11

p.desterlich


People also ask

How JWT token validation works in net core?

JSON Web Tokens (commonly known as JWT) is an open standard to pass data between client and server, and enables you to transmit data back and forth between the server and the consumers in a secure manner. This article talks about how you can take advantage of JWTs to protect APIs.

How JWT refresh token works C#?

In the login method, we create an access token and refresh token and return to the response of the request. In the refresh method, we are checking the expired access token and existing token and if both are confirmed correctly then a new access token and refresh token generate and return to the response.


1 Answers

This can be handled using the JwtBearerEvents that is connected to the JwtBearerOptions instance provided to AddJwtBearer. Specifically, there's an OnMessageReceived event that can be implemented to provide the token itself. Here's an example:

services.AddAuthentication(...)
    .AddJwtBearer(jwtBearerOptions =>
    {
        // ...

        jwtBearerOptions.Events = new JwtBearerEvents
        {
            OnMessageReceived = ctx =>
            {
                // Access ctx.Request here for the query-string, route, etc.
                ctx.Token = "";
                return Task.CompletedTask;
            }
        };
    })

You can see how this is used in the source code:

// event can set the token
await Events.MessageReceived(messageReceivedContext);

// ...

// If application retrieved token from somewhere else, use that.
token = messageReceivedContext.Token;
like image 146
Kirk Larkin Avatar answered Sep 17 '22 16:09

Kirk Larkin