6

I'm working with a 3rd party company who are providing an API along with an unusual security approach.

The security approach is essentially using a JWT by itself (no oauth). What's odd is that they're expecting us (the client) to create the token which seems the opposite way round.

My API will communicating directly with this 3rd party API.

The JWT is signed using a secret they provide but since we are creating it, the payload including what endpoints we can hit and the expiry time is determined by us.

Usually I would expect the 3rd party to provide a signed JWT after we've authenticated.

Has anyone come across this approach before, whereby the client is responsible for creating the token?

fml
  • 517
  • 4
  • 15
  • Do they want you to create it, or do they want you to get it from a federated auth Service? Didn't they give you any documentation about the auth protocol? The claims you have to provide, the algorithm to use, something? – Laiv Mar 20 '19 at 19:50
  • 1
    Yes they want me to create it using a a secret they provide. But the scopes (which service endpoints I can use) I put into the token along with the expiry time I want. I just think it's odd that I'm creating it. I would have expected something similar to Client Credentials in Oauth. – fml Mar 20 '19 at 19:54
  • Looks like the signsture is the only they need to trust in your client. Like an API key. It's indeed a curious protocol. Kinda self-servcie. Hope someone comes with good answer. It also could answer a question I did time ago about claims collisions. This scenario seems adecute for that problem. – Laiv Mar 20 '19 at 20:12
  • I have a similar situation - did you ever gain any insights? In my case the third party has admitted that they don't yet support a proper Client Credentials flow for their REST API, and have an alternative whereby the pre-shared client secret is used to sign a client-generated JWT (which only includes an internal account id under which the REST operations are authorized and performed) that is validated on the server for authentication, and an access token issued. In theory this sounds OK, but they also require the client secret as a header to the token request, which can't be good, right? – lesscode Sep 05 '19 at 18:18

1 Answers1

4

I have to admit, I've just created a REST API using the approach like the one described above: We provide a username and secret for each client, which is allowed to access our REST service.

The client has to generate a new JWT for each REST call and has to add the token to the request header.

Why did I choose this approach and what are the advantages and disadvantages in my eyes?

First of all, we only have a single server providing the REST service. There is no need for us to use a different authentication server, which seems to be the most common use for JWT.

In a normal JWT scenario, the client provides credentials (username and password) to the server and receives a server generated JWT containing API access information as payload. This JWT is then used for each REST call over and over again. Of course, the password is to be kept secret by the client.

My approach works as follows:

The client creates a JWT with the following payload:

  • username
  • HTTP Method and name of REST method to call
  • timestamp
  • unique nonce

The JWT is signed using the client's secret.

The server identifies the user via the username from he payload and validates the signiture using the user's secret stored on the server.

In my eyes, this approach has the following advantages:

  • The secret (like the password in the normal approach) has to be kept secret by the client too, BUT is never transferred between client and server.

Additional security against man in the middle and replay attacks:

  • the token is only valid for one REST call because of the unique nonce.
  • the token can only be used for the REST service the client wanted to call, because HTTP method and REST service name is included in the payload.
  • The JWT is only valid for a limited time (1 Minute in our case) because of the timestamp.
  • The user can be identified by the server via the username, the server than manages access rights by retrieving user configuration from an internal database. If you have many user related properties and settings, this has some benefits over putting all those information into the static JWT as you would in the normal approach, which might result in a quite large token and which might even reveal some credential information. For example, if some REST calls are charged to the client and you really don't look up user information on the server side, pricing information might be included into the JWT.

Disadvantages might be:

  • JWT must be created on client side for each call, which might consume some processing power and adds overhead to the implementation.
  • The server must acquire user information from the database (or some kind of cache) for each call.
  • The pre shared secret must be kept secret on client and server side. The server must know the secret and can not store only a hash like you can do with a password.

So my use of JWT does not focus on using an single authentication server or a stateless serverside, but on hardening against MITM and replay attacks.

Every opinion on this approach is welcome.

JDEV
  • 41
  • 3
  • 1
    I think this authentication scheme is reasonable, but you will get confused clients like the person who asked this question because _this is not what is generally recognised as a JWT_ - you are reusing the technology, but not the _concepts_ associated with it. It's like taking some sealing wax and then writing a signature on it with a biro - it might be effective, but it's an unusual combination that will surprise people. (I'm also wondering if this should have been a Question rather than an Answer, so that this comment could be expanded into an answer with more thoughts on your reasoning.) – IMSoP Jul 08 '20 at 13:42