I would like to set up an IT solution based on the Front / Back principle.
Front side I would use a technology like React, Angular and Back side I would use a technology like java spring boot to implement controller Rest.
The front will make Rest requests on the back to retrieve data.
I would like to add a security concept to the solution by implementing the JWT standard on the back. Thus the client, knowing the secret, could request a token back and could make requests by specifying the token via the header of the request.
I found several tutorials explaining how to set up this type of solutions. In particular: https://medium.com/#nydiarra/secure-...n-e57a25806c50
In this tutorial, we assume that we define somewhere (here in a H2 database) the different users of the app and their role (admin or standard).
So the front could ask a token but it would have to indicate the user and his password and the secret defined. The back looks in the database and gives a token relative to the role defined for this user.
My question is simple. Do we have to define users and roles if we want to use JWT?
What I would have liked to do is not to inform and not to store potential users and their roles.
Simply the front requests a token with the secret without giving user and the back gives a token. Which will be used later in the header of the requests.
Related
We have an application that loads information(user specific) from the external system upon successful authentication, to avoid round trips to the external system for each api call, we are planning create a custom JWT token with user specific information for the first time user authenticated, then the token is send to user in each response header using http interceptor and in the front-end we are including the custom token in every request along with authorization token. Is this correct approach? Do you have any alternative suggestions?
I have looked into other distributed caching techniques like redis but not so appealing for a small usecase. Our payload length does not exceed 4 to 5K hence inclined towards the JWT option
it is ok to include user information that allows you to handle the user authorization inside the access token. Just beware of the privacy implication and perhaps not include personal information like social security number or date-of-birth or other identifiable information.
Also, make sure the token size does not get to big. The other option is to lookup and cache the user information in the API's when it receives a new access token.
Some systems including ASP.NET Core do store the token inside the session cookie in an encrypted form, so that the end user can't see or access the stored tokens.
If you are developing a SPA application, the using the BFF pattern is one approach.
I have a difficulty in understanding Spring Security and any tutorial I found was not tailored to my needs. So maybe I'll explain what I think and what I want to accomplish.
I want to create a website with Kotlin/Java backend and frontend in React. This website would need to have users with different roles (user, admin).
And (I think) the thing I need is some kind of backend that has 2 endpoints:
register (to create users in database)
login (to, based on username and password, fetch user info and role) - as some kind of token? This returned token would be then used by frontend to display specific options (i.e. do not display "ban user" for regular users) and it also would be sent to backend for checking if the person who requests for specific endpoint really should be able to call this endpoint (i.e. it should be forbidden for regular users to use "ban user" endpoint)
What should I read about, what keywords should I look into to achieve this?
For purely the Spring Boot part of the implementation, the following should do
(/register) Signup/Register endpoint taking all required parameters for your business logic. e.g Username , Password , Full Name as well the roles
(/login) For logging in , you need a token forwarded to the front end, which will then use this token in the header for the session. JWT tokens seems like what you need(sample below). For the other part of your requirement, you can keep the user object (with roles) in the session as well as check user role on the backend in the "ban user" endpoint and process accordingly.
JWT Authentication with Spring Boot
I found a good starting point in the following sample
https://github.com/bezkoder/spring-boot-spring-security-jwt-authentication
For a more complete example
https://www.bezkoder.com/spring-boot-react-jwt-auth/
Credits to
https://www.bezkoder.com/
I have come a cross Youtube Video that covers all the scenarios that your looking for and extra, with Email verification links as well. i hope this will definitely help you
Java Tutorial - Complete User Login and Registration Backend + Email Verification
There is a lot of good content on the internet that explains how to secure a Spring API with Keycloak: Create a Client that represents the API Service in Keycloak and use a link like the one below to get the access and refresh token:
<Domain>/auth/realms/<realm>/protocol/openid-connect/auth/{some parameters}
This yields both tokens. So far so good.
Now, however, I am not sure how the flow for the frontend accessing the API should look like.
Should the frontend directly access this endpoint and, therefore, obtain the access and refresh token? That would mean that the API can only have the access-type public because there is no way to store the client (the API) secret securely.
Or should there be a third server that somehow stores the refresh token for each user, that the user can call if his access token is no longer valid. This server would then use the client's refresh token (and the client secret that could be stored securely, since it would be in the backend) to get a new access token from Keycloak and would forward it to the user.
I guess the main question that I am asking is, whether the client/user should get the refresh token.
If one needs to implement a logic according to the second option, I would be interested in a link or description of how something like this can be done in Spring.
I think, in either case you need to use the Authorization Code Flow. The implicit flow, which was recommended for SPAs (frontends without a backend server) in former versions of OAuth2 must not be used anymore.
The best option is to have a backend server, so the user retrieves the auth code via redirection and the backend server exchanges this auth code with the access and refresh tokens (and keep them without forwarding them to the frontend).
If there is no backend in place and your frontend needs to retrieve and hold the tokens directly, I would recommend to use the Authorization Code Flow with a public client and the PKCE extension (which - put simply - ensures that the entity asking for the auth code is the same as the entity asking for the tokens and that the auth code was not stolen and used by a foreign entity). There are several sources with more detailed explanations, which might help you, for example: https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce
Hope this helps you with your architectural considerations.
I have a number of stateless Microservices behind API Gateway and I want to make sure that a user request containing valid Authorization JWT token cannot access resources of other users.
Currently, my API Gateway only validates if the JWT is not expired and is valid.
To prevent a user request with valid JWT access resources of other users, I was going to use Spring's Method Level Security and check if the principal user id matches the userId in the request URL path. But that means that, in each microservice, I need to add Spring Security, create an authorization filter, and create a security context based on the information I read from JWT. I will need to recreate the Spring Security Context in every single Microservice.
Is it a correct way to do it? If not, what is another way to prevent a user request containing valid JWT to access the resources of other users?
Please advise me.
How you’re handling it is usually the correct approach. In order for each service to remain de-coupled from others it’s important it is able to determine which methods/endpoints care about the user scope and which ones don’t. More rules and logic in the gateway means more restrictions on what individual services can do.
That being said, if you have globally predictable rules that apply to all services you have a case for putting the logic in the gateway. Something like JWT verification is an example of such a rule that is standardized enough that you can make assumptions about what underlying services would want to do with the token upon receiving it (verify it). If you have a rule you can safely apply globally, you can pull it out of the services and put it in the gateway. Otherwise, you’re better off with a bit of duplication so that you don’t create hurdles that would prevent services from handling input differently.
I'm creating an API server which will be consumed by a mobile app that I will work on later. I have yet to see any reference of API best practices related to user flow and returned data even after searching for several hours.
My question is whether the login response of an API should return the a personal access token with the refresh token along with the user info? Or should I just return the token and make another API call for getting the user info.
I could just do what I have in mind but I'm trying to learn the best practices so that I don't have to adjust a lot of things later.
I need suggestions as well as good references related to my question.
Thank you.
It depends on what you are using for your authentication. If you are using libraries like Laravel Passport or JWT, you can have the token endpoint which returns the access token, refresh token, validity period and the token type (Bearer). You can then have an authenticated endpoint which will be used to get a user's profile based of the token passed in the request header.
However, if you go through the documentation for those libraries, in most there is an allowance to manually generate a token. You can use this in a custom endpoint that will return the token as well as the user profile Passport Manually Generate Token.
If you are using JWT, you can also embed a few user properties in the token itself. The client can the get the profile info from the JWT itself without having to make a round trip to the server. Passport ADD Profile to JWT
If you have a custom way in which you are handling authentication, you can pass the token as well as the user profile in the same response.
In the end, it's up to you to decide what suits you best.
Have you looked at OpenID Connect? It's another layer on top of OAuth 2.0 and provides user authentication (OAuth 2.0 does not cover authentication, it just assumes it happens) and ways to find information about the current user.
It has the concept of an ID_token, in addition to the OAuth access token, and also provides a /userinfo endpoint to retrieve information about the user.
You could put user information in your access token, but security best practice is to NOT allow your access token to be accessible from JavaScript (i.e. use HTTP_ONLY cookies to store your access token).