How to secure the Rest webservice by token based authentication? - java

I have created few rest services using jersey implementation.
In security concerns, service can invoke by any one. So I decided to use the token based authentication system.
I wrote one filter in spring security which handles every request before its hits the server.
One login service were created so user can invoke this service by passing the username and password for valid credentials it will generates the access token and expiry date and saves it in Hashmap and DB and returned as a response to the user.
For remaining services user have to pass the generated token in header to access the JAX-RS services.
All these process are coded by us i.e., generation,storage and expiration of the token.
Since we have some security API like oauth1,oauth2 in market is it good to provide the security for rest service by above mentioned way???
Is oauth api will suits my requirement . If it is please guide me how to achieve this ?
Please help me out with valuable suggestions ???
Thanks in advance.

We've been in a similiar position before starting with our rest api. The only difference we had no exisitng code. So basically we saw 2 choices
Run our own Tokenhandling, that what you already have
Use something existing, i.e. oauth2
Our main requirement was authentification via token and we prefered an existing solution. So we just run with oauth2 in form of spring-security-oauth2, even we are not using the whole self authorization stuff.
What i like and probably had missed in an own implementation is that a token generally identifies a user and a client combination and that clients can have rights too. Its nice to have this extra layer of security in our rest api, so i can block early on before even hitting one line of our code.
In form of spring-security-oauth2 its proven code, which works and like much of spring its customizable. Example: In our first version we did use the provided JdbcTokenstore for storing the token, but as requirements changed, we just coded our own and switched it in the config.
The disadvantage of using at least spring-security-oauth2 is that the whole authorization flow is normally webbased and needs communication between the client, the user and our app. As this would not work with our clients we had to trigger the token generation, etc ourselfs, which is doable with spring, but needed some code exploration :-)
If i had to build it again with java and where already using spring, i'd go with spring-security-oauth2 and the oauth way again. But when i had an existing working solution and dont need any of the oauth stuff i would keep the homegrown solution.

Related

Keycloak and SpringBoot

I started playing with Keycloak, but I have a question. While reading articles, I always found examples where a client (let's say Angular) is logging in on Keycloak, it gets a bearer and then it send the bearer to the SpringBoot application. The backend, so, validates that the bearer is valid and, if so, it allows you accessing the desired endpoint.
But it's not enough in my opinion. I don't need just to login, I would need the entire functionality - let's say I have a backend application and I need a user. I could have a basic todo-application, how do I know for which backend user I am actually accesing an endpoint?
Straight question: how can I bind my own backend user (stored in the DB from backend) to the one from Keycloak?
What is the best way to do it? The only thing that I found online and into the Keycloack documenation is that I could move the logic of logging in from client (Angular) to backend (SpringBoot). Is this the way to go?
Imagine like I'm creating my manual /login endpoint on backend on which I would then call the Keycloak server (Keycloak REST client?) and I would pass myself (as a backend) the bearer to the client.
Please help me with an explanation if I'm right or wrong, what's the best practice, maybe help me with an online example, because I just found out the too easy ones.
OpenID tokens are rich
Keycloak is an OpenID provider and emits JWTs. You already have the standard OpenID info about user identity in the token (matching requested scopes), plus some Keycloak specific stuff like roles plus whatever you add with "mappers".
All the data required for User Authentication (identity) and Authorization (access-control) should be embedded in access-tokens.
How to bind user data between Keycloak and your backend
In my opinion, the best option is to leave user management to Keycloak (do not duplicate what is already provided by Keycloak). An exception is if you already have a large user database, then you should read the doc or blog posts to bind Keycloak to this DB instead of using its own.
Spring clients and resource-servers configuration
I have detailed that for Spring Boot 3 in this other answer: Use Keycloak Spring Adapter with Spring Boot 3
In addition to explaining configuration with Spring Boot client and resource-server starters, it links to alternate Spring Boot starters which are probably easier to use and more portable (while building on top of spring-boot-starter-oauth2-resource-server).
I Also have a set of tutorials from most basic RBAC to advanced access-control involving the accessed resource itself as well as standard and private OpenID claims from the token (user details) there.
Tokens private claims
For performance reason, it is a waste to query a DB (or call a web-service) when evaluating access-control rules after decoding a JWT: this happens for each request.
It is much more efficient to put this data in the tokens as private claims: this happens only once for each access-token issuance.
Keycloak provides with quite a few "mappers" you can configure to enrich tokens and also allows you to write your own. Sample project with a custom Keycloak mapper here. This is a multi-module maven project composed of:
a custom "mapper" responsible for adding a private claim to the tokens
a web-service which exposes the data used to set the value of this claim
a resource-server reading this private claim to take access-control decisions
The simplest way to do it is to consider that the job of storing users will be delegated to your Keycloak server. But you can implement some roles and checks manually with in-memory or any database of your preference too.
I invite you to follow some documentation about OAuth 2 and Keycloak, to make requests to get a valid token for a time period and to make others request inside that time period to get datas. You can use CURL to make requests or web/software tools like Postman.
Be careful, a lot of Keycloak Adapters are deprecated ones since some months.
I would echo BendaThierry's comments. Look into OAuth2 and Keycloak. The Bearer token you receive from Keycloak will have user information in it (typically in the Claims). This way you can have user preferences or features in your backend without needing to manage the authorization and authentication that Keycloak does.
There are lots of great resource include Spring's website tutorials (like https://spring.io/guides/tutorials/spring-boot-oauth2/) and Baeldung (https://www.baeldung.com/).

SpringBoot JWT security how to

I am trying to implement simple JWT security with token refresh in my web app. Probably, the question has been asked numerous times and I am digging for an answer but can't seem to find it after a month of searching.
I have two models for the user in the database and they should have different role type ADMIN and USER. ADMIN type needs to access his url endpoints and USER his own upon successful email and password login.
I am trying to avoid oauth because I do not need enterprise like implementation.
Could anyone refer me to a good guide that explains how stuff works or just explain by himself with a code sample? You would help me alot! Thanks.
You may want to try JJWT if you're looking for a simple to use JWT library for Java. It's well documented and easy to integrate into Spring Boot apps.
At the very least, you'll need to write your own service for generating tokens (using JJWT), a filter for pre-processing the request and generating an Authentication, and an AuthenticationProvider for performing the actual processing/validation of the token content (again with JJWT) and to populate roles/authorities or any other information that might be required by your Authentication implementation.
This method of implementing JWT based authentication does not require any components from Spring's OAuth2 implementation.
https://github.com/jwtk/jjwt
https://stormpath.com/blog/jjwt-how-it-works-why

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.

User Token authentication Spring MVC RESTful API

I would like to secure our REST API with user token.
User does an initial request to the API to obtain an access token (must provide own credentials - login and password)
Service find the user by provided credentials
If is a user found, service creates an unique token with time expiration and returns it back to the user (token expiration can be defined as now() + 15minutes - is it enough? What is a standard expiration time for such tokens?)
User must provide this token in all his requests OR asks for new token when is expiring and API process original request
I would like to ask you - is there in Spring framework native support for such authentication flow - I'll be happy with some simple example or URL to Spring doc? If so, what do I need to use? I have studied Spring docs and read many tutorials, and It seems there is a support for everything and I need to know what is the best for my issue.
For token-based authorisation to resources, one framework that will inevitably come-up will be oAuth
oAuth will help you achieve exactly the workflow that you desire e.g. that a user can authenticate and then be given a token to access a defined set of resources via an API. It is however fairly heavyweight and it is definitely worth taking the time to understand how it works and that it exactly fits the picture of your requirements.
The "official" site is here. There are two versions of oAuth, so again this will help you to understand which the the right one for you.
As for Spring Security integration, there is a Spring Security oAuth project. The documentation for this is pretty good both at the level of how the integration works with Spring Security, but also in terms of helping you understand that oAuth is the right solution for your project.

Java REST service using authentication token

On my web app using Java EE 6. I want to expose some of my functionality as a Json Rest Service. I want to use authentication tokens for login, User will send their username, password and server will send back a token, which will be used to authorize the user on their further requests for a given time..
A few questions bothering me so far;
When the server creates the token and sends to client, should server save it in a DB OR in a Bean using something like a hashtable as userid-token pairs?
Can I get some help using any Java EE specific API or this has to be all custom code?
Heres my input:
I would save the token in DB, in case you need to restart the server you don't want to lose all your user's tokens. You could potentially save it in memory as well to speed up requests and only look it up in DB if it is not found in memory.
I would accept the token in the header. I would put the rest service on HTTPS so the request is encrypted and then you don't need to worry about encrypting the token manually in the request
I would probably look at JAX-RS and see what features it offers
I recently blogged on how to set up Role-based authorization in a JAX-RS REST API using both a simple session token approach and a more secure method of signing requests using the session token as a shared secret.
It boils down to:
Get a session token from the server along with some identifier for the user
Use the token to encrypt the information in the request
Also use a timestamp and nonce value to prevent MITM attacks
Never pass the session token back and forth except for when retrieving it initially
Have an expiry policy on session tokens
Saving the token in a bean or hash table would not be persistent. A DB would persist between executions.
If you are going to be using REST then you can either pass the authentication in the parameters to the method, or in the request header itself. Encryption is a different matter. I guess it depends on the scale of the system, and how open it is. If security is a top importance, then yes, you should find some form of encryption.
I have done similar things using the Spring Framework, and Spring Security. These things are relatively simple using this. To write custom code is to reinvent the wheel. There are many frameworks out there which will help you. However, you would then have the learning curve of the framework.

Categories