Pixelairport's avatar

Extra security layer: Only allow requests from server or IP.

I build a Gateway (Laravel with user auth) and a microservice. The gateway has access to the microservice via Client Credentials Grant Tokens (machine to machine). Everything works fine, but I think there could be another security layer. Because now I create the access token and store it in a table in the gateway to access the microservice. If a will hack my service, he can steal the token and can access microservice directly. I want to avoid this and ask myself, if there is a way to check in microservice, from where the request came? I only want to allow a defined url or ip. I thought it has something to do with cors, but when i set something in config, laravel does not block me, at a post request, when I set only put. Is there a better solution for this all?

I also thought about encrypt the user id and also pass it with headers and encrypt it on microservice. But this is maybe also another security layer.

0 likes
8 replies
martinbean's avatar

@pixelairport If you know that there’s only going to be one other micro service accessing this service then yeah, you could create some middleware that only accepts requests from a specific IP address:

class CheckRequestIsComingFromUpstreamService
{
    public function handle(Request $request, Closure $next)
    {
        if ($request->ip() === 'XXX.XXX.XXX.XXX') {
            return $next($request);
        }

        abort(403);
    }
}

That will reject requests coming from any other IP address. So if someone did get your access tokens, they wouldn’t be able to authenticate and invoke your service from any other machine.

The downside is, this means the upstream service has to have a static IP address, and if the IP address does change, then you need to change either your codebase or a configuration value somewhere.

1 like
Pixelairport's avatar

You are right. I forgot that ip could change. I try to find another solution.

Maybe it is possible that I also send the access_token, which every user gets for the gateway after auth, to the microservice. So I send the machine-to-machine access token to access the microservice and pass the access_token from the user through the gateway to microservice...

I will check this tomorrow, if this could be a solution. And write here tomorrow if this works or not. It is just an idea right now.

martinbean's avatar

@pixelairport You’re really over-complicating things. Sending two access tokens in a request? Completely not how OAuth works.

If you have micro services and you only want them talking to each other, then put them in a private network so they can communicate with each other, but people can’t make direct requests from the internet.

1 like
Pixelairport's avatar

@martinbean maybe you are right I i think too much about what could be. I think i will start with the machine-to-machine access_token and when the idea works and project grows i will think about more solutions like private network and get help from someone who is a professional in it. thx that is what i needed to go on with my work :)

1 like
Pixelairport's avatar

I just got an idea or maybe how to do it better. Hope someone will read it, because i marked this post already as solved.

I connected the Gateway/Auth-Server the whole time with a "Client Credentials Grant Token" to the microservice. The user authenticates before(with his Access Token) to the gateway and each request must be done to the request.

Now the idea... what if i dont do it with the "Client Credentials Grant Token" (machine-to-machine) and build a middleware in the microservice. Then i forward not only the request from the gateway, also the bearer of the user access token in authorization. And in the middleware of the microservice i do a second request back to gateway, where the microservice try to check at the gateway, if the user is logged in and get the infos for the user: UserId, Which plan user have, and so on... Is that to much traffic? Or would this be a good solution. That would avoid, that users can use any user id. They must be logged into my app and have their own key. If someone will hack everything, he needs all the current user keys instead only of one to have all access to the microservice.

I know I should keep it simple, but i also want a good solution instead of refactor all things later. And this sounds really good for my. I try to find the best way... simple but also clean and secure.

Pixelairport's avatar
Pixelairport
OP
Best Answer
Level 12

I did a test and it seems to be the best solution. I made a scribble to aks here, if there is something which is against this solution?

Flow

For me this solution works, I understand it, think that is clear, ... but maybe I forgot something, which is not good with this solution.

Pixelairport's avatar

Ok. I talked to a friend, who knows a lot more about this topic. He says that it is a better solution.

Please or to participate in this conversation.