简体   繁体   中英

Securing REST api with Token

I have been struggling with this the last couple of days and haven't found a reliable, understandable solution on the web.

I have a web app that is comprised of a rest api and a presentation layer consuming it. Presentation layer has a login form, the data introduced by the user is sent to the REST api which then uses a third party service to authenticate the user. This part I have already set up.

What I want now is to inrtoduce a token-based authentication for every subsequent request so I don't have to send credentials on every request and then authenticate again against the third party service.

So basically, using Spring Security (v. 3.1.3), I am lost as to how to create a reliable, secure token, return it to the requester, then authenticate request based on said token.

Can you point me to the right direction? Or to some example online?

  • How do you generate the token? How do you return the token to the client?
  • How would you send the token in subsequent requests?
  • How do you set the whole thing up so the first time you can somehow send the credentials (user/pass) then the subsequent requests send only the token?
  • How do you authenticate against the token?
  • I've seen implementations where token includes some expiryTime. So what happnes after expiryTime is exhausted? The user must login again, even if he's been making requests the whole time? Should I renew the token "behind the scenes"?

Is the server-side REST application stateful or stateless? If stateful, you won't need to do anything special using a regular HTTP Session. Just start using Spring Security and if the client and server are already exchanging session information, your protected API endpoints will work out of the box. The only caveat is if you have CSRF protection enabled, in which case you will need to tweak the client a little bit. Details for this are in the Spring Security documentation.

On the other hand, if the REST application is stateless, you will have to use a token-based approach like you have proposed. See my answer to a similar post for details. If you do choose to follow the steps in that answer, answers to your questions are:

  • The token has to be generated on the server-side. If you go through the sample code linked to my answer, you will see that I have replaced the default HTTP-session-dependent infrastructure of Spring Security with a cache-based infrastructure. In the session-based implementation, the unique conversation identifier, which is the session ID, is generated by the servlet container, whereas in the custom implementation, the identifier, which is the token, is generated within the application. Specifically, I have used a SecureRandom instance to generate strong tokens.
  • The token is sent back by the client as an HTTP header. This protects the content over an SSL channel.
  • The trick is to implement four very simple interfaces from Spring Security. My sample app has full details. The whole process took me less than an hour.
  • Authentication against the token is done automatically by Spring Security. We simply need to provide an implementation for storing and retrieving tokens, which is straightforward and takes only a few lines of code.
  • In my sample app I have used an expirable cache with sliding expiration for storing the tokens. If a client keeps sending requests periodically, the server keeps on accessing the cache for the authentication token, thereby keeping the token alive in the cache. Tokens are evicted from the cache only after a period of inactivity equaling or exceeding the cache expiration period.

So overall, a token-based authentication/authorization approach can be easily implemented with Spring Security and leveraging a caching library like EHCACHE.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM