I don't believe either is inherently wrong, but here are my thoughts on both, and a description of my preferred pattern.
For the first one
This is no doubt a common and traditional pattern, but the challenges I see with the first are three-fold
- Scalability/Concentration risks. In this case every request has to go through a complex gateway logic that might not scale well. This is especially problematic in micro-service architectures where many services call each other all the time.
- You also have "configuration blast radius" in terms of that gateway becoming critical architecture everyone is scared of touching especially as the logic complexity increases
- The "security isn't my responsibility mindset". If we say we make calls to the business service from the gateway how does the service Authenticate/authorize the call? Does it just trust it blindly/rely on network access control to prevent traffic even hitting it? If so, what happens if network is accidentally or maliciously misconfigured? In addition, if a security log just shows "access from gateway" you will need to correlate logs against the API-GW logs
For the second one
I feel this is better as your API-GW configuration is less complex, but you still have a bottle-neck on the AAA service in the data-plane.
My preferred solution
I am therefore a big fan of a federated split responsibility between AuthN and AuthZ. In this approach you have a central Authentication Server (think OAuth AS) that deals with MFA/authentication and then vends credentials (think JWT). This JWT can have encoded (custom) claims such as "is_admin" "group_membership: ["x", "y", "z"] and is signed by the issuer.
Your API-GW can now simply check that the tokens presented are valid (signed by the trusted issuer and not expired) but doesn't need to concern itself with authorizing ultimate access. Instead, the business service can then look at the (passed through) token (re-verify validity of token) and make the decision whether to honor the request based on the claims contained within.
In this solution you don't have much complex bottle-necking logic, your service is protected by the API-GW, but it can autonomously decide what to do with a request.
What's more this approach allows you direct internal service-to-service communication without needing to go through an API-GW at all and without having data-plane dependencies on a shared concentration point.
Unfortunately, this entire space isn't well or easily documented. The first time I looked at JWTs and OAuth my head was spinning for two weeks, but once you understand it the benefits are not easily discounted.
The basics are explained quite well here and I've taken the following image from there. This also seems to be an interesting resource, but it's behind a sign-up wall with limited preview Book - Microservices Security in Action
(API-GW not shown but imagine it in front of the Resource Server)