How do I implement the basic authentication in Spring Cloud API Gateway? - spring

I have 2 secured resource microservices and 1 authentication service and another API Gateway.
Authentication service can generate JWT Token given username and password. It also can validate a JWT token.
So, I want to implement security at the API Gateway only such that on receiving a request, it will first fetch a bearer token from the authentication service and forward the request to the secured resource service. I would like to get some idea how to implement that in API Gateway. Should I make it just in an aggregate fashion, like it would be a sync call which will first make a request to auth service and next forward the request to resource service?
Now, if I want to add the support of OAuth as well, which I know the spring cloud API Gateway already has the support for this via global filters.
But, I am wondering about the legacy bearer token which is generated by the custom authentication service.. How do I ensure this?
Any suggestion would be appreciated.
Thanks in advance!

Related

Spring Cloud - Micoservice Authentication propagation

I am building an application using microservice architecture. I am using Eureka for service discovery with Spring Cloud Gateway for request routing. For authentication mechanism I am issuing JWT tokens (in auth service). What is the best practice when it comes to propagating Authentication so I can get logged user information in each service which is after the gateway?
So far I've came up/found couple of possible solutions:
In gateway add headers for relevant user information, and in each service create filter which would take said headers and create Authentication object and store it into SecurityContextHolder. The downside of this approach is I can't just plug and play services outside my application.
Pass the token coming from the client through the gateway to the each service, where I would have JWTFilter which would validate token and extract the user information. Downside I see with this approach is I have to have jwt secret shared between each service or stored on each service, and I would have to implement JWT logic, producing duplicate code.
Final solution is having something like oAuth token introspection endpoint in auth service which would be called from each service (filter) once the request reaches it.
I implemented the filter logic for validating the user token in the gateway service, but I would like to use role based authorization on each endpoint (service) differently (ie. user service has endpoint for creating users (ADMIN), and for fetching user information (ANY ROLE)).
I opted for something like your option 2 and use spring-boot to configure JWT decoder from an OIDC authorization-server (Keycloak).
Configuring OpenID resource-servers is super easy (more options in parent folder), and authorization-server JWT public signing key is retrieved automatically by spring JWT decoder.
All that is required is ensuring that Authorization header with JWT bearer is correctly propagated between services.

Spring/spring boot authorisation using JWT tokens

Looking for suggestions on how to go about with microservices authorisation.
I'm using the spring/spring boot for all them microservices
I'm able to authenticate via spring cloud gateway before reaching the actual microservices using JWT tokens however when it comes to authorisation i'm unsure on how to do it.
I would like handle the authorisation internally for each of the endpoints in the business microservice.
Is there a way to pass the JWT token to the microservice or do i need to call the authserver to get the roles within the user ?
Actually, both works.
You can put the roles in the token, when you need it, decode it. Or decode it in the gateway and pass it all the way.
If you don't want to put too much data in the token, you can call the auth server as needed.

How to secure Spring Cloud microservices using Spring Security?

Here is the authorization service. It has endpoints to login and receive a JWT using either a custom username/password or social OAuth (Facebook, GitHub etc.).
I have a Eureka server setup and Zuul gateway service. From what I understand, there are two ways to go about implementing secure microservices. You either proxy requests through the auth service, or you send requests to the requested service (Ex. Service A) and service A authorizes using the auth service.
I would like to use the second way, however I'm having trouble implementing it. Is my understanding correct? Is there a way to setup service A somehow so that certain paths (configured using Ant matchers) will have to authorize using the auth service, which will set the SecurityContext appropriately and inject a UserPrincipal into the request. If anyone can point me to a good guide for this that would be much appreciated.

Keycloak authentication flow in a microservices based environment

I want to use Keycloak in a microservices based environment, where authentication is based on OpenID endpoints REST calls ("/token", no redirection to keycloak login page), a flow that I thought of would be something like this:
1. Front-end SPA retrieves the tokens from the "/token" endpoint and stores in browser's localStorage, then sends it with every request.
2. Gateway-level authentication: Acess Token is passed from the front end to the gateway, gateway consults Keycloak server to check if the token is still valid (not invalidated by a logout end-point call).
3. Micro-service based authorization: Acess Token is passed from the Gateway to the microservices, using Spring Boot adapter the microservices check the signature of the token offline (bearer-only client?) then based on the role in the token do the authorization.
My questions are: Does this flow make sense or can you suggest another flow? What type of Keycloak clients to use? What's an ideal way to pass Tokens using Spring Boot Adapter, and should it be done like that in the first place? Please keep in mind that I am not a Keycloak expert, I've done my research but I still have doubts.
Your Front-end SPA should be public-client and springboot micro service should be Bearer only Client and Gateway could be Confidential Client.
You can check the Keycloak provided oidc adapters. For springboot you use the keycloak provided adapter
Similar solution using api gateway is discussed here

Relaying the incoming token downstream to other services

I'm trying to understand 100% how a Resource Server works, relaying the incoming token downstream to other services.
I have a microservice architecture with spring boot eureka, with Bearer authentication against an #EnableAuthorizationServer.
I use an Edge Service in zuul with #EnableZuulProxy and #EnableOAuth2Sso for request entry, and I wanted security to be centralized at that point, but of course, I can't leave the microservices without security and each of them is an #EnableResourceServer.
Everything works ok.
The question is:
Either with a security.oauth2.resource.user-info-uri pointing to the oauth server or to the edge service, that bearer token is always validated against the oauth server, i.e. if it passes through 10 microservices a request, will it validate the token 10 times against the oauth server?
Isn't there any way that I don't have to request 10 times to the oauth server if the token is valid?
All right,
It seems that for a Bearer token type, it is always necessary to authenticate on each resource server against the authentication server.
The solution is to use JWT tokens.
As explained in:
https://developer.okta.com/blog/2018/04/02/client-creds-with-spring-boot#extra-credit-reduce-the-number-of-calls-to-the-authorization-server
We use signed JWTs which means you can validate them locally instead of making an additional request from the API service to the authorization server on each request.
That's it.

Resources