clarifications on spring authorization server with multiple instances - spring

I have a clarification question.
I plan to build an authorization service with spring security and spring authorization server. Say I have multiple instances of the auth services that are behind a load balancer. My understanding is that the following will happen and assume that we have two instances A and B:
when a user is trying to access a protected resource it will first redirect to the auth service (a request to instance A with /oauth2/authorize?response_type=code&client_id=some_client_id&scope=some_scope&state=some_random_string&redirect_uri=http://some_redirect_url/)
the auth service will then redirect the user to login because the security filter finds out the user is not authenticated (response from instance A)
the user will enter the credential with formLogin (at this time the request might hit instance B)
In this case, how does instance B gets all the parameters such as client_id, redirect_url, and so on?
update 1:
do I need do something like this .loginPage("/login?client_id=&client_id=some_client_id") to pass down the information

Related

Securing rest and actuator endpoints using custom token and http session

I have a spring boot app where the API #Controller endpoints are secured using a token that is contained in the http header. The token needs to be extracted from the header and validated against an internal cache to make sure it is valid. If the token is valid then the request can proceed to the controller and if it is not valid then it should return a 401 to the caller.
I also have another requirement to secure some of the actuator end points. When the user tries to use the browser to access the respective actuator endpoint, it will check for a user session if no session exists then the request is redirected to the spring login page. When they login I need to extract the username and password and validate using an external service. If valid a session can be created for the user and they can then use the hawtio endpoint. The session needs to store role based information so that when the user tries to perform JMX operations it will only allow them to perform the appropriate read only / write if they have the requisite role.
Any pointers regarding how you'd try and tackle this would be most welcome. I am unsure whether this is achieved by specifying addFilterBefore or addFilter and I don't understand how having authenticated the user for the actuator I go about creating a session that can be stored in the context and checked later on for subsequent requests.
Thanks

How to pass JWT token from a microservice that consumes another microservice?

I have two microservices say A and B. In all REST endpoints for both microservices, I have implemented JWT authentication. A user has to hit an endpoint ("/login") with username and password and generate a token and pass this as a RequestHeader to all end points in both the services.
Say in microservice A, I have an endpoint ("test1/createSomething"). In B I have another have an endpoint ("test2/getSomething"). Now I am able to call ("test2/getSomething") from service B, in ("test1/createSomething") in service A using Feign client.
But I am not sure how to implement this in a way that I generate the JWT token in service A and pass it along to service B, to consume its services.
Please help. Beginner in microservices and exploring things.
One approach you can try is by having a separate session/jwt service.
Roles and responsibility of that service would be to store/validate and authenticate having following endpoints.
create_token() : create new JWT token with given input data(say user info, expiration time etc)
is_token_valid() : check if token is valid or not
So you can have a flow like this :-
1. First hit to login-service > login service getting token from jwt-service > returning jwt token to UI/client.
2. UI/Client passing received jwt token to service-b via headers> which indeed pass jwt token to service-a, where each service independently calls is_token_valid() of jwt-service and process the request only after getting success response.
To implement this in spring-boot, what you can do is by adding an interceptor layer, that is being called before every Controller class, where is reads headers, extracts jwt-token and validates that from jwt-service.
You can look at the similar answer here.
Another reference here

OpenId-Connect (OIDC) with Spring Security but without sticky sessions or central storage

We want to configure our service with OIDC authentication against a keycloak server.
We are using spring security 5.2.0 with spring boot 2.2.0.
There are multiple instances of our service and we do not want to share any state between them with central storage (e.g. databases, distributed caches, ...), nor use sticky sessions. That's why we already implemented two custom cookie-based repositories for authorization info that would normally reside in the server-side session. (CookieBasedRequestCache and CookieBasedAuthorizationRequestRepository). That way the oidc redirect flow works except for the last step where the user is redirected to the original url:
After successul login, keycloak redirects back to our instance with a code. This instance (let's call it 'A') validates the OAuth2AuthorizationResponse against the initial keycloak authorization request. It gets the information from a cookie we saved earlier in the login process to avoid Spring Security's session management.
Now, if the authorization response is successfully validated, instance 'A' sends a final redirect to the original URL that the user requested before logging in. If this request is answered by the same instance 'A', everything works fine. But if a different instance (say 'B') answers the request, it doesn't work because B doesn't know anything about the user's authentication state.
Questions:
Is there a cookie-based JWT repository we could use to save the access token across instances? Or how would one implement it?
Where in spring security's code (filter chain?) is the check whether the user is authenticated? This would be helpful for answering the final redirect to the original url.

Where should I create user in SPA using Oauth2

I am working on an application with spring boot backend, that I want to secure with OAuth2 using implicit flow. The front end will be angular (SPA). For the initial phase I will have Authorization and Resource server on the same instance, but want to be able to seperate it later on.
I do understand that authorization "takes place" on the Authorization server and then a token is used to access resources. But how do I add a new user to the system? Should there be a registration (password reset etc.) endpoint on Authorization server or the Resource Server?
It makes sense to put it on Authorization server, so when I add a new application that uses it will be able to add a new user to the system.
From other point of view the Authorization server should be used only for authorization, so user creation could be delegated to a resource server.
Usually the registration process is implemented in the resource server, so this endpoint and similar endpoints like retrieving a forgotten password, resetting the password etc all of them lives in the resource server, as they are part of the logic of your application, not part of the authorisation itself.

API gateway and microservice authentication

How API Gateway and Micro services works.
Could anyone explain the basic flow of Micro service architecture with Gateway. I couldn't find the proper answer.
Say we have auth server and customer micro service running on separate instances and in front of all the services we have an API gateway.
My question is.
when user try to log in using username and password, the API gateway call auth server and return the access token to user.
Then user trying to access the specific url (/customers - customer micro service) that is running on separate instance.
what API Gateway do ?
validate the token with auth server and get the user id and pass the request to customer service with the user id ?
OR
validate the token and pass the request to customer microservice with the access token ? and customer microservice responsible is to the check the user id (Make an HTTP call to auth server) ?
I think that the most common approach is to use API gateway also as a security gateway, which means that API gateway is responsible for SSL termination and token validation. If token validation is successfully you can put user ID or user API key as a header and forward the request to microservice. Moreover you may also decide to perform not only authentication but also authorisation on the API gateway (usually with help of API management solutions).
Regarding your option #2 - I see no point in validating token 2 times. Best practise is to perform security validations on the edge, because in case of failed validation you use less resources (reject earlier)
To Answer your question , it is close to option #2 that you have mentioned . The API gateway will generally check the validity of the authentication token and then pass over the request to your micro-service . However you need to decide at design time if your micro-service will also do another level of verification of the token.
Please do note that the API gateway will not be enforcing Authorization , the authorization is something that your micro-service will have to enforce.

Resources