Quarkus use the /metrics endpoint to provide metrics data, the /health endpoint to provide the application status (UP or DOWN) and the /openapi endpoint to provide information about the available endpoints. This endpoints are defined by the Eclipse Microprofile Specifications.
By default this endpoints are public. I want protect this endpoints to only authenticated and authorized users can access.
How to protect this endpoints using Quarkus?
I want that the applications returns 403 for unauthorized users.
To authenticate I want use a basic authentication or a JWT token.
Is possible create a filter to this endpoints?
This configuration should help:
quarkus.http.auth.permission.public.paths=/health/*,/metrics/*,/openapi/*
quarkus.http.auth.permission.public.policy=authenticated
You can start from the basic authentication as recommended here.
HTH
Related
Currently doing some research to setup an (azure) api gateway with oauth (jwt token) security.
an external partner/app sends a request to an api endpoint published on the gateway including a valid JWT-token in the header that gets validated by the gateway against AzureAD for example. When validated the request is routed to the backend service. No problems here.
My question is, what is best practice for the external app to obtain that JWT-token (to use for the api call) ?
Obviously, It could send a request to AzureAD with a clientid+secret to obtain a valid JWT token. But to do so it has to call my internal AzureAD directly ? Is this the way to do it ?
or should I expose a 'get-jwt-token' api on my api gateway and route that request to AD ? How should I secure that API ? with basic auth ?
or am I missing something, and is there a much better best/proven practice ?
HOSTING BEST PRACTICE
A reverse proxy or API gateway is placed in front of both APIs and the Authorization Server (AS). This ensures that an attacker who somehow gains access to the back end entry point cannot access data sources.
OAUTH REQUESTS TO GET TOKENS
OAuth requests are typically proxied straight through the reverse proxy / API gateway to the AS with no extra logic. All credentials, auditing of login attempts etc remain in the AS.
MANAGED SERVICES
If using Azure AD as a cloud managed AS, this is a special case: the system is already hardened for internet clients, so most companies don't add their own proxying - though it is possible to do so.
FURTHER INFO
The first of these covers the infra setup and the second gives you an idea of extensibility options once a reverse proxy / gateway is in place.
IAM Primer
API Gateway Guides
I see different opinions among software engineers regarding where to place authentication in a Microservice architecture.
Many support the idea that authentication should be placed at the API gateway level and only the Authorization at Microservice level.
For authentication I mean checking a JWT that was issued after authentication with credentials, for example...
Now, if the API gateway is the only entry point of our backend then it is reasonable to have it in the Frontline when it comes to authenticate the requests.
The problem is that the API gateway, being a proxy, shouldn't really be bound to the underlying services, right?
Let's say that some of the endpoints require authentication and some of them are publicly accessible. I feel that in this case it's better to have it at the Microservice, since the Microservice knows all the details of the API that it exposes.
Otherwise the API gateway should ask the Microservice if the endpoint is public or not or get this information from a database.
But wouldn't be too much of overhead to perform this request to the service/database everytime the gateway is hit?
Furthermore, depending on the framework we use to implement the security layer we might not have the chance to check the accessibility of an endpoint at runtime. So, whenever we make an endpoint public we should redeploy the gateway to get the new information about what requires authentication and what not.
What are your suggestions regarding this topic?
Looking at it strictly from a security perspective.
From what I have seen with microservice architectures, the gateway only performs authentication, each micro service / endpoint needs to handle its own authorization checks at a bare minimum.
So for your public URLs, the gateway would not perform any authentication checks.
For your private/secured endpoints, the gateway will perform authentication checks and authorization checks at a microservice level, but you will still need to handle the business rules to be followed.
Example:
/public/article1 - does not need any authentication or authorization checks
/private/newsletter - requires authentication from gateway, but may not require authorization checks from the microservice
/private/account - should require both authentication + authorization check from gateway as well as from the microservice to make sure you are accessing only your account.
I'm reading a tutorial provided by AWS explaining how to break up a monolithic NodeJS application into a microservice architectured one.
Here is a link to it.
One important piece is missing from the simple application example they've provided and that is user authentication.
My question is, where does authentication fit into all this?
How do you allow users to authenticate to all these services separately?
I am specifically looking for an answer that does not involve AWS Cogntio. I would like to have my own service perform user authentication/management.
First, there is more than one approach for this common problem.
Here is one popular take:
Divide your world to authentication (you are who you say you are) and authorization (you are permitted to do this action).
As a policy, every service decides on authorization by itself. Leave the authentication to a single point in the system - the authentication gateway - usually combined inside the API gateway.
This gateway forwards requests from clients to the services, after authenticating, with a trusted payload stating that the requester is indeed who they say they are. Its then up to the service to decide whether the request is allowed.
An implementation can be done using several methods. A JWT is one such method.
The authenticator creates a JWT after receiving correct credentials, and the client uses this JWT in every request to each service.
If you want to write your own auth, it can be a service like the others. Part of it would be a small client middleware that you run at all other service endpoints which require protection (golang example for middleware).
An alternative to a middleware is to run a dedicated API Gateway that queries the auth service before relaying the requests to the actual services. AWS also has a solution for those and you can write custom authentication handlers that will call your own auth service.
It is important to centralize the authentication, even for a microservices approach for a single product. So I'm assuming you will be looking at having an Identity Service(Authentication Service) which will handle the authentication and issue a token. The other microservices will be acting as the service providers which will validate the token issued.
Note: In standards like OpenID connect, the id_token issued is in the format of JWT which is also stateless and self-contained with singed information about the user. So individual Microservices doesn't have to communicate with the authentication service for each token validation. However, you can look at implementing or using Refresh tokens to renew tokens without requiring users to login again.
Depending on the technology you choose, it will change the nature how you issue the tokens and validate.
e.g:
ExpressJS framework for backend - You can verify the tokens and routes in a Node Middleware Handler using Passport.
If you use API Gateway in front of your Microservice endpoints you can use a Custom Authorizer Lambda to verify the tokens.
However, it is recommended to use a standard protocol like OpenID connect so that you can be compatible with Identity Federation, SSO behaviors in future.
Since you have mentioned that you are hoping to have your own solution, it will come also with some challenges to address,
Password Policies
Supporting standards (OpenID Connect)
Security (Encryption at rest and transit especially for PIDs)
SSO, MFA & Federation support etc.
IDS/IPS
In addition to non-functional requirements like scalability, reliability, performance. Although these requirements might not arise in the beginning, I have seen many come down the line, when products get matured, especially for compliance.
That's why most people encourage to use an identity server or service like Cognito, Auth0 & etc to get a better ROI.
I tried to implement custom Authentication via a authentication endpoint in an azure mobile app. I've created an Api Controller, that creates the Jwt using Azures AppServiceLoginHandler.CreateToken method. When I post to this controller with turned off Azure App Service Authentication, I get a token, but when I want to use it later, I always receive a "401 Unauthorized".
But when I turn the setting on in the Azure Portal, and send the very same request
I get:
The requested resource does not support http method 'GET'.
I'm not changing any code, and I'm certainly using a POST request - The exact same request, that works with turned off App Service Authentication.
My Code is essentially the same as here:
https://www.newventuresoftware.com/blog/custom-authentication-with-azure-mobile-apps
Could someone enlighten me here? Do I need additional configuration somewhere?
As adrian hall's book about Custom Authentication states as follows:
You must turn on Authentication / Authorization in your App Service. Set the Action to take when request is not authenticated to Allow Request (no action) and do not configure any of the supported authentication providers.
For custom authentication, you need to turn on the Authentication / Authorization in your app service for authenticating your token. Moreover, I would recommend you leverage fiddler to capture the network traces to narrow this issue. Additionally, you need to make sure that you send the custom login request with HTTPS. Details, you could follow this similar issue.
is there a way to block REST API calls to a non authorized client?
is there a way to make the API "limited" to (public for) only small number of well defined clients?
thanks :-)
You can deploy mutually-authenticated SSL between your clients and your server. You can use self-signed certificates here so you don't need to buy any from a CA. This will ensure that your server only accepts requests from clients that have the client-side certificate (configure your server to only accept the self-signed client certificates deployed on your clients for client authentication).
If you are using RESTFul HTTP
you can add an HttpServletFilter to your web.xml which prevents unauthorized clients from accessing your REST Methods.
See
Securing JAX-RS and RESTeasy
If you use the Spring Framework you and you don't want to implement your own HttServletFilter you can use Spring Security
You just need to implement security mechanisms in your RESTful Service, so it denies access to unauthorized clients (with a 404 or 401 response code). There are several ways to achieve this:
Relay on HTTP authentication mechanisms, like Basic Authentication
Implement a Custom Authentication framework, that overcomes HTTP Basic Authentication limitations. Amazon has an interesting approach that includes custom HTTP headers and supports hashing.
Use an existing security framework and add its capabilities to your service. Spring Security sounds like a great option.