I need an advice on securing interaction between an application App and a microservice RecordApp.
App is the main application, where all users are registered and do some activity. RecordApp is a utility application where App users can store records that publicly visible in the App (like sub-twitter). RecordApp knows nothing about users, but each record ("tweet") needs to have an author. I need to provide ability to use the RecordApp from the frontend and don't use the App like a proxy. I have some options to do this:
The first is: User passes authentication on the App server and receives JWT token (that was signed using App public key) that tells that the user has name "User1" and can create public records. Then user sends this to RecordApp, it validates it (using RecordApp secret key) and sees that this user can create a record and then creates it. But if some hacker steals the User cookie, then the hacker can post malicious records by the name of "User1". I could solve this by setting httpOnly flag for the cookie, but App and RecordApp have different domains, so that wouldn't work.
What do I do to secure such microservice?
The second option is as user passes authentication on the App server, send to the user a public_key that will be used to sign jwt with the record contents. If the hacker will be able to steal it from the-middle, then they just can post this message unchanged. But what do I do to protect the public key then?
Thanks in advance!
-
"But if some hacker steals the User cookie" Then don't save the JWT in a cookie?nvoigt– nvoigt07/10/2019 16:26:40Commented Jul 10, 2019 at 16:26
-
Where do I store it then? Local storage is XSS vulnerable... Other options?Defake– Defake07/10/2019 16:40:52Commented Jul 10, 2019 at 16:40
1 Answer 1
App is the main application, where all users are registered and do some activity. RecordApp is a utility application where App users can store records that publicly visible in the App
In your case , App
can act as authorization server (identity provider) and RecordApp
is resource server. Your first option (using JWT) is good to go, when your frontend needs to access resource server at the first time :
- firstly it request a new JWT that is specific to the resource server
RecordApp
to authorization serverApp
(note you can also share the same JWT among different resource servers, but it is not recommended for security concern) - The authorization server
App
receives the request, once it ensures the request is sent by authenticated client, it selects which key pair to sign a new JWT - sign the JWT using private key of the chosen key pair managed by authorization server
App
- put the signed JWT within response body of client's request
- the frontend receives the response from
App
and saves the signed JWT in memory (e.g. locally-scoped variable in your JavaScript code) instead of persisting it to cookie or localstorage, which should be good if your frontend is SPA or mobile app (even if it's not SPA there are other methods to transfer the JWT between web pages e.g. using iframe) - The frontend sends another request with the signed JWT to the resource server
RecordApp
, soRecordApp
can check user permissions by verifying the JWT using the public key .
The final step leads to another question : How does resource server RecordApp
get public key for verifying a signed JWT ?
This is where JWK and JWKS come into play , the authorization server App
is responsible to provide an interface (e.g. REST API endpoint) for other resource servers to check out all valid public keys in JWKS form , also the signed JWT has to contain (minimal) key information such as the key id for the signature (kid
field) , and the URL to fetch the JWKS resources. By doing so you don't need to pass the public key around your frontend and backend services.
-
What's the problem with passing the public key around?Defake– Defake08/30/2021 11:47:03Commented Aug 30, 2021 at 11:47
-
As you mentioned :
The second option is as user passes authentication on the App server, send to the user a public_key that will be used to sign jwt with the record contents ...
If I understand your question correctly , your second option makes authenticated frontend user receive public key first , then the user can send requests toRecordApp
along with the received public key , right ?T.H.– T.H.09/04/2021 03:41:30Commented Sep 4, 2021 at 3:41