Question

Folks,

What is a simplest way to track consumer applications accessing RESTful API services inside department. We do not restrict access - no authentication/authorization - open for invocation, trusted environment. No tools like OAuth AuthZ servers or API management yet... but might be heading there at some point.

For now we thought to request consumers just to include some custom HTTP Header like X-Client-Id and log it on the server side for stats etc.. But knowing that in the future we might want to switch to more standard ways of doing things ... what would be best alternative to have to change less code in the future ?

  • Have the "clientId" in the Authorization: OAuth token (like access token)
  • Have JWT token in the Authorization header (looks too much - signing,base 64 etc for simple client id tracking ...)

Any ideas would be appreciated

No correct solution

OTHER TIPS

We recently implemented this for one of our REST platforms and we used a combination of BOTH the points you mentioned, meaning Authorization header & JWT token. Although, JWT is ONLY for authentication and GETTING an access_token (oauth token) which is later used with calling actual resource apis. I will discuss how we handled this situation and you can decide on how you want to implement it.

1) Authentication

Client sends a JWT to your authentication service (/api/oauth2/auth). (If you want more reading on JWT, you can read here and here of how JWT is implemented by google and how you can use spring-security-jwt libary to handle all the signing and encrypting/decrypting). You get the "clientId" out of JWT after decrypting and verifying the signature and after server does all the authentication, you respond back with a 'refresh_token' and an 'access_token'. Server will save the access_token as well and map it to the clientId so that when client makes requests using access_token, you can know which client is making the request. The access_token expires in some time (ideally in an hour) and when it expires, the client uses the 'refresh_token' to get a new access token by posting refresh_token to some refresh token url (/api/oauth2/auth/token)

2) Authorization

Client takes the 'access_token' and uses the access token to make all the subsequent requests on all other apis (/api/*). Ideally, the access_token is sent as a part of the "Authorization" header. Server uses request filters (if you are using JAX-RS, you can use something like ContainerFilterRequest to add filters to specific url patterns and intercept them) to filter EACH request and parse out the Authorization header value. You will get the access_token from the header and from the access_token you can get the clientId that you mapped in step 1). You can do other authorization logic in the security filter and if everything goes through, you can use this information to LOG that clientId and the request that the client made.

This way you can kill 2 birds with one stone : Implement a security layer & log the information about customers (what calls they are making, how many time etc. etc.). In case you don't want to implement security filter just yet (as you mentioned it might be in the future), for now, the clients can just pass on the "clientId" (base64encoded or not, upto you) as a part of "Authorization" header. If all the calls are from a "trusted" network, it should be ok, although not as secure. This way, when you ACTUALLY implement a JWT and Oauth based security layer, all you have to do is change your ContainerFilterRequest logic to parse out access_token instead of client id (as mentioned in step # 2).

I hope this helps ! For more information on security filters you can have a look at this answer: Basic Authentication of a resource in Dropwizard. It says dropwizard, but it mostly talks about JAX-RS.

To implement full AuthN/AuthZ layer for consumer tracking would be an overkill for now. We thought to use either to Authorzation header to pass custom client_id token:

  Authorization: Custom  <Client_Id>

or to use some limited version of JWT (no signatures as there no intent to validate them) as access token

  Authorization: JWT <JWT>

Where JWT could be:

{"alg":"none","typ":"JWT"}
{
   "iss":"Client_ID",
   "aud": REST Service URI,
   "iat":1328550785
}

I do not see description of access_token format in the specification http://tools.ietf.org/search/draft-ietf-oauth-v2-23#section-1.4

Are there any contraints to use JWT as access token?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top