Spring Gateway and Authentication routes - spring

I have a simple Spring Gateway project that uses 3 microservices - 1 service for doing authentication and 2 "secured" microservices (i.e. all requests to these services must be authenticated).
The authentication service which is responsible for authentication (generate JWT tokens) works fine via the Gateway.
As in I can access it via the Gateway to create tokens and via the Gateway to confirm if a token is valid.
In my scenario when the user attempts to access a “secure” microservice I want
Call the auth service to verify the user has the correct JWT token
If the use does not have the required permission confirmed in (a) return some Http status 404 code with a specific message
If the user is authenticated confirmed by (a) allow the call to proceed to request route
Reading around seems to suggest I would need to apply some filter on the Spring Gateway routes to do this.
The examples on https://cloud.spring.io/spring-cloud-gateway/multi/multi__developer_guide.html#_writing_custom_gatewayfilter_factories aren’t too clear on how to achieve this. Wondering is this the reccomended approach?
If so can someone point me in the direction of what this would look like in terms of the routing code in Spring Gateway
builder.routes()
.route(route -> route.path("/auth/**")
.uri(LOAD_BALANCED_AUTHENTICATION_SERVICE)
.id("authentication-service"))
.route(route -> route.path("/images/**")
.filters(SOME_AUTHENTICATION_FILTER)
.uri(LOAD_BALANCED_IMAGES_SERVICE)
.id("images-service"))
.route(route -> route.path("/inbox/**")
.filters(SOME_AUTHENTICATION_FILTER)
.uri(LOAD_BALANCED_INBOX_SERVICE)
.id("inbox-service"))
.build();
Note I haven't implemented the filter (SOME_AUTHENTICATION_FILTER) shown above yet as I'm not clear from the examples how to call the authentication service from the filter. Also unclear from the examples how the filters would terminate a request or allow the request to proceed.

As I understand, you have two questions, first one the routing recommended flow; and as you defined exactly will be good, if the filter worked correctly move route to Service X.
For the other part, How to define the custom filter? you need to do the authorization check inside it using your secure service; there is a good example which can tell you how to handle this, and how to terminate the request also with descriptive messages.
You can find it here Spring Cloud Gateway Custom Filter

Related

SPRING Boot App Integration with IdP/PING Federate

I'm new here and posting the first question ever, and coming straight to the point.
I have a N Tier Application, Front UI on AngularJS, backend on Spring Boot and a NoSQL DB with some caching attached to it.
I'm struggling in getting the SSO configured using PING Identity for my Home grown application for following reason.
Lack of knowledge on PING SSO.
The knowledge that i have gained so far only gives me limited visibility on how i can achieve the solution for having a successful SSO configured.
Summarized Solution:
Front End UI -- Speaks to Middleware Service for Auth(current design) -- Middleware Service acts as a Interceptor for my backend services(also known as BFF) which handles all my tokens for necessary handshaking. --- Backend Services performs logics & functions
Problem: Trying to bring in PING for SSO is confusing:
as far as i know PING can be configured in 2 ways.
OAUTH2.0
SAML Based Auth.
in Oauth, User would access, Ping URL with context path which will internally speak to PING federate and AD and return a Token.. i might be wrong here. hence need clarification! as im not an expert on PING.
the confusion in case of OAUTH is, its totally confusing.. i have used oauth before, but via PING using it for the first time.
in SAML based Auth, again a PING URL with context path which will internally perform its work and then add some Assertion and then return the SAML token to a POST endpoint.
the confusion in case of SAML is as following:
if i configure my middleware to receive the SAML Token, how can i redirect the user to welcome page?
PS the middleware has some encryption logic that cannot be by passed!
any help in this matter would be highly appreciated. as im looking to see what options do i have on PING or even on my Springboot app.

Best practices to secure rest api with gateway and spring security OAuth [duplicate]

I have developed a set of microservices (resource servers) using Spring Boot 1.5.x + OAuth2 with JWT. Right now each microservice is protected using Spring Security i.e. JWT access token is verified at individual resource server level. API Gateway does not have spring security in place, so it just routes the requests to appropriate server and propagates the authentication headers to downstream services.
I wanted to know if there are any disadvantages of this setup compared to the one where AccessToken is verified at API gateway level only. Or is it just a matter of opinion? Doesn't keeping security at API Gateway level breaks principle of loose coupling, because each microservice may better understand the role of a given user in its own context?
API management can do a small check on your JWT (fail early), BUT your microservices are the only one that can really manage all the security stuff !
If you set security only on api management it means that someone that can access your network will be able to push request to your API unauthenticated.
You will not be able to log who do what. And finally, if you need to set some kind of ACL, it will not be possible (When you ask to list orders, you can only list YOUR order).
Perhaps you will think of decoding your JWT on the api management layers and push a header with user name to your backend to prevent all the thing I spoke about above, but I think it is not really a good practice.
First, access to network will means I'm able to be anybody. Then JWT is much more than just a username. For instance, perhaps you use scope on your authentication layers. ( scope read orders / scope modify orders / scope delete orders). This is useful to restrict what an application can do (either at client_id level) or what a user accept to give to the application ( scope share email ...).
For this JWT on the backoffice is mandatory.
Ok you can do like username and extract data on api management and put specific headers to call backend, but really ? why do specific stuff ? oauth2 with JWT can do this for you.
Well this is an interesting question. In our team we discussed about this topic a lot. Basically you have some parameters affecting the individual answer to this question. But you should always decode and verify granted tokens on the microservice level, too. Because they contain relevant information for authentication and in some cases even for authorization. If your microservices run in a enclosed environment (e.g. on enclosed Kubernetes cluster, where only the API-Gateway is available to the outside) you could use this "mixed" solution.
You can really consider just to verify the AccessToken at the API-Gateway and let the other microservices rely on the API Gateway. The API Gateway could than exchange the AccessToken into another AuthToken, only valid in the microservice-context. This new generated AuthToken can for example contain more sensitive application-bound information, because it is not exposed to the client. The Client gets only a so called opaque token. See https://medium.com/tech-tajawal/microservice-authentication-and-authorization-solutions-e0e5e74b248a

API Gateway: Mixture Of Authenticated and Unauthenticated Endpoints

I have been working on creating a platform utilizing microservices architecture with an API Gateway. One question that I'm stuck on, is how to have the API Gateway handle both authenticated and unauthenticated endpoints.
Here is a simplified and rough diagram of the system I am thinking about
For my system, I'll be using Auth0, and I think I want to have the service check if the token is valid using the public key, instead of the gateway doing it. This gives me more flexibility if I want to make one of my services public someday. And I think I want to keep my gateway small.
But how will the gateway handle a mixture of both authenticated an unauthenticated endpoints? I.E. I want to make the GET endpoint "open", and the POST endpoint require login. Which entity should manage whether an endpoint is "open" or "requires login", the gateway or the service?
Should I always have the gateway pass along the request to the service, regardless of whether the user is logged in or not, and have the service return a 401?
Or should the gateway contain some logic about which endpoints require login, and return 401 if there is no token in the request? Skipping the service entirely.
Yes it is configured on the gateway you will be using. For example on AWS API gateway you can have a lambda custom gateway authorizer for access points. The authorizer function can 'authorize' by returning ok for all request to that endpoint.
More reading here
This is one of main responsibilities of API Gateways in my opinion. It may depend on the specific API Gateway but one elegant solution that we used was:
All microservices define their endpoints and if they are protected or not in a descriptor file.
When it is deployed (perhaps in CI) it registers these definitions in the API Gateway
API Gateway accepts the request and check if it is protected or not
API Gateway may enrich request with user info if protected
All requests beyond Gateway is accepted secure to be accepted by services
This way we separate the concern of authentication from business logic / features

Securing SpringBoot API for desktop application client

I have a SpringBoot Micro-Service based backend API that uses Zuul as a gateway proxy between a JavaFX Desktop Application. Right now there is no security in place, but I am looking to secure the backend with Spring Security, however, every tutorial I seem to run across seems to be based on web-apps and I haven't seen anything for my particular use case. I don't know much about spring security but would like to know if I can accomplish my goals with it, and if so, what modules or examples should I be looking for.
Goals:
Provide a way for my API to know that requests are coming from the desktop app itself, I think the technical term for this is assigning the desktop app a client id and then having the Zuul Server validate that the client id is that off the desktop app before accepting the request. This should be the case for all requests
Only allow API traffic through the Zuul Proxy, all of the downstream requests to the micro-services behind the Zuul gateway should only be accepted if they are coming from the Zuul Server itself.
Allow requests for logging in and registering as a new user without any type of security other than the desktop client id discussed in 1.
When a user provides a successful username/password on login, they are returned a JWT which is then stored in the JavaFX application and used for all of the other requests to the backend.
Configure the token to expire after a specific time frame, say like 90 minutes and provide a method for automatically refreshing an expired token as long as the users account is still valid. For this, I don't want the user to have to re-login, I just want it to check behind the scenes to make sure their account is still valid and then issue a new token if needed.
Have user based roles so certain features, methods, endpoints, etc. are only accessible to users with the valid role. Within the GUI these features will be hidden or disabled, but I would still like a layer of security on the server side to protect against unwanted access in case someone was able to modify the app.
I am just writing down answers to each of your goals :
Passing the client Id in every request from desktop application doesnt make sense, instead you client Id and secret can be passed during authenticaiton call, Like we have in Oauth 2.0 framework. Rest https calls should be made from client, So to avoid tampering of request, You can also go for mutual SSL between your client application and Zuul API gateway, It assures that call is coming from Desktop client only.
Yes, Zuul api gateway should be single entry point to your application, Your internal microservices should not be exposed to public.
For user registeration, Client authentication can be achieved using client Id and secret
Correct, You can also create http only cookie at backend, which will include your jwt token only.
Token refresh can be achieved at zuul api gateway, if session is active, make call to refresh token endpoint to get new access token.
On server side, At zuul proxy you can validate the incoming bearer token expiry along with signature validation, with generic claims too. Now at microservices level spring security can be used for role based access control for particular methods.

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