Problem:
We have a Spring MVC-based RESTful API which contains sensitive information. The API should be secured, however sending the user’s credentials (user/pass combo) with each request is not desirable. Per REST guidelines (and internal business requirements), the server must remain stateless. The API will be consumed by another server in a mashup-style approach.
Requirements:
-
Client makes a request to
.../authenticate(unprotected URL) with credentials; server returns a secure token which contains enough information for the server to validate future requests and remain stateless. This would likely consist of the same information as Spring Security’s Remember-Me Token. -
Client makes subsequent requests to various (protected) URLs, appending the previously obtained token as a query parameter (or, less desirably, an HTTP request header).
-
Client cannot be expected to store cookies.
-
Since we use Spring already, the solution should make use of Spring Security.
We’ve been banging our heads against the wall trying to make this work, so hopefully someone out there has already solved this problem.
Given the above scenario, how might you solve this particular need?
We managed to get this working exactly as described in the OP, and hopefully someone else can make use of the solution. Here’s what we did:
Set up the security context like so:
As you can see, we’ve created a custom
AuthenticationEntryPoint, which basically just returns a401 Unauthorizedif the request wasn’t authenticated in the filter chain by ourAuthenticationTokenProcessingFilter.CustomAuthenticationEntryPoint:
AuthenticationTokenProcessingFilter:
Obviously,
TokenUtilscontains some privy (and very case-specific) code and can’t be readily shared. Here’s its interface:That ought to get you off to a good start.