Oauth2 flow to issue tokens for registered users automatically - spring-boot

I have an endpoint, which I want to protect using Oauth2 and spring boot. The users register on the website and after the successful payment, a token with specific expiry should be issued automatically and delivered to the user. The User can revoke the token in their panel and get a new token manually.
I don't want to use password grant type as it requires sending the username and password for each request. the authorization code grant type, requires the user to enter their credentials which doesn't fit my need for automatic generation of tokens after successful payment. I'm not sure if using client credentials grant type is a good idea for my need. I could use a new client for each new user. But this seems not right to me. But correct me if I'm wrong. any idea which oauth flow I should use?

You want to authenticate end-users with OAuth2? Use authorization-code (with PKCE).
In your statements, there seem to be a confusion between authorization-server (issues tokens) and resource-server (subscriptions are resources too in my opinion). Have a look at this article for OAuth2 refresher and spring resource-server security conf.
Also, it seems to be a one-to-one relation between access-token and payed subscription. This is probably a mistake: access-token should be short lived (like a few minutes). Are your subscriptions that short?
I see two options here:
have your authorization-server add a private claim with subscription status to JWT access-token (or introspection details) and check this claim value in spring-security expressions (#PreAuthorize("..."))
configure a custom authentication converter in spring security which calls a #Repository to read subscription status in database, based on identity contained in access-token
First solution is way more efficient (persisted subscription status is retrieved from DB only when a new access-token is issued) but requires your authorization-server to be flexible enough for you to add private claim with values from a web-service or a DB. I have a tutorial to do so in Keycloak. read it AFTER the article above.

Related

How does authentification with JWT work in Spring Boot

How does authentication with JWT in Spring Boot work? Do I return my custom user and I set a filed called token to the JWT or do I return a JWT with all user information within in it to be extracted later? With the JWT for authorization I need my custom user information returned to be displayed in the app.
Here is few point JWT is designed to work:
Clients logs in by sending their credentials to the identity provider
The identity provider verifies the credentials; if all is OK, it retrieves the user data, generates a JWT containing user details and permissions that will be used to access the services, and it also sets the expiration on the JWT (which might be unlimited).
Client stores the JWT for a limited or unlimited amount of time, depending on the expiration set by the identity provider.
Client sends the stored JWT in an Authorization header for every request to the service provider.
For each request, the service provider takes the JWT from the Authorization header and decrypts it, if needed, validates the signature, and if everything is OK, extracts the user data and permissions. Based on this data solely, and again without looking up further details in the database or contacting the identity provider, it can accept or deny the client request. The only requirement is that the identity and service providers have an agreement on encryption so that service can verify the signature or even decrypt which identity was encrypted
A good hands-on example is here.

JWT with JDBC token store vs JSESSION ID

I have implemented a spring boot application which does authentication and authorization using Spring OAuth2.
I am using JDBC token store to main the token issued to the client for performing Custom claim verification and some other user status verification during application run-time.
The question is, since i had used traditional JSESSIONID with CSRF token, i cannot find any advantage with the new OAuth standards because after login i would store the user details in the session and retrieve it whenever needed similarly for OAuth i store the User details in the JWT token itself and decode the token every time to get the user information, also i need to hit the database anyway for custom claim verification such as JTI verification .
Everyone says JWT is for stateless application but with JDBC token store i'm holding all the token that is issued to each client. Also there is an additional overhead to purge the expired token which will be done automatically with Session. Also i'm using refresh token as the way to implement session timeout.
Therefore can anyone explain me, when should i use JSESSIONID and when to use JWT ? My application is running on AWS architecture.
From my experience, cookie-based authentication sufficiently complicates scaling and load-balancing. If you have authenticated via the first service replica, your cookie will be not appliable to another replica, cause all sessions are stored in memory. So, if you want to scale your service in the future, session-based authentication can make things much more complex.

What is the advantage of providing a Tokenized Authentication in an application with Spring Boot Backend over SecurityContextHolder?

I was getting started with Spring Boot and Angular 7 and I came across user authentication.
Let's assume the following: I have a frontend with Angular 7 and a Backend with Spring Boot that offers API's that can be accessed via HTTP.
So I know that usually the frontend authenticates the user with e.g. JWT that stores all necessary information about the user that might be needed. But I came across the SecurityContextHoler of Spring Boot Security:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
This allows me to simply access granted Authorities and so on. So I thought about the following:
Using JWT for the frontend grants the following advantages (as far as I know):
* Users can identify when using API's
* Users may be prevented from certain UI-Elements (based on roles stored in JWT)
* Modification prevention due to checksum (invalid token afterwards)
Now I could also add a check in my Controller in the Backend that checks the SecurityContextHolder for user permission (something like a Service that checks the current context permissions vs the needed permission and returns true/false). Wouldn't that be even more save, since it is in the backend (so in my inmagination everything that runs server-sided is always a little more save than what runs client-sided)?
I can store information in the frontend (like roles and a username) to use them for the UI-based-access prevention to still have the same advantages as JWT provides, but I do not have the "effort" of implementing the JWT creation.
But obviously it is not common to do it that way (at least I never saw it), so what is the advantage of the Tokenization?
They are not mutually exclusive. You would use what you call "Tokenized Authentication", like an oAuth2 Bearer token most likely in a JWT when the Authentication is performed by a separate system from your Spring Boot backend. For example, you may be using Okta, Keycloak, Google or Facebook to authenticate the user.
At a minimum, your Spring Boot backend stores the username extracted from the JWT in the Authentication. You can get Spring Boot to extract any roles in the token and add those to Authentication::grantedAuthorites. If your backend system, has it's own set of roles in addition to what's in the token, then the backend could implement a PrincipalExtractor to load a UserDetails object for this user from the database as the Principal and merge the roles in the token with those store in the local database.
You'll probably want to security certain methods in your backend with method security annotations like #PreAuthorize(), since you shouldn't trust the front end. The method security will check permissions, like hasRole("ADMIN") or hasPermission(object, 'READ') using the Principal object in SecurityContextHolder.getContext().getAuthentication();
In the end, the token assures the backend the user accessing it is who they say they are, i.e. Authentication, but does not necessarily tell the backend what they are Authorized to do. Yes, if you control the Authentication server you can include roles in the JWT, but roles don't usually provide as fine a grained control as is required.
Independent of what level of security you implement, the token is translated into an Authorization so you can use the Spring Security framework to manage access within your backend code.
There are 3 type of token in spring security OAuth2:
1. InMemory token Store
2.JWT token store
3.JDBC token store
So now you’re talking the JWT token store. The most powerful of JWT token store is prevent the authorization server load against to the database for checking such as role,token expired so it is related database load performance. Since all the information such as: role,username, token expire ,etc include in token itself. So the authorization server or other resource sever may using the public key to verify this token itself without invoke to data store.
Hope helpful! ☺️

Spring oAuth2 with JWT using different authorization and resource servers

So I currently have this POC that I'm tinkering right now. I was thinking if it was possible that I can implement a Spring oAuth2 with JWT with a Authorization Server and a Resource Server both in different projects?
Flow goes like this User gets a token or passes through the Authorization Server and as long as he has the token and it's not expired he can make requests on the resource server.
I think that is the usual way to implement that. You have one authorization service providing tokens, either itself is backed by a database containing user information or maybe is asking another user service if the credentials are valid. The returned tokens can be used to make authorized request against the resource service(s).
Maybe take a look at the grant flow here.

External OAuth2 integration with own OAuth2 spring server

I'm trying to integrate Facebook OAuth2 authentication with my own OAuth2 server. Just to be clear the scenario is the following:
I have a OAuth2 Server that is responsible for authenticating our users. I implemented a custom AuthenticationProvider that checks for the credentials provided and builds a UserDetails object if successful.
I also have a rest-api that is also a ResourceServer (runs in a different application). So users after being authenticated they can access our rest-api providing therefore the token.
The token information is shared using JDBC.
Everything works fine as expected, but now I want to add external authentication providers such as Facebook.
My question is: what's the best way to do this? What's the expected flow? From the top of my head I would imagine something like:
User authenticates with facebook
Facebook provides a token
User sends the token to our OAuth2 server
I check the token validity with facebook
I authenticate the user using the authentication provider
The server gets back to the user with a new token issued by my OAuth2 server which the user will use from now on to ask for resources
Is this right? If so, how can I send the facebook token to my OAuth2 server? Is there some kind of standard? Should I make up new parameters for that? For instance I will be needing some way to differentiate facebook authentications from user/password ones.
Am I suppose to use my own AuthenticationProvider to validate this facebook user? It seems strange then return a UserDetails object that doesn't have a password...
Also, how to register users and auto log them in? Do I have to expose an endpoint of my own or is there some OAuth2 magic for that as well?
Any thoughts?
Facebook has some very good documentation on this with the correct flow and how you should handle the process.
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2
You are on the right track, and I think the facebook documentation should help clear up any questions you may be having.
Additional Information is here:
https://developers.facebook.com/docs/facebook-login/v2.2

Resources