Search code examples
angularspring-securityjwtkeycloakgateway

How to configure AngularApp behind a Spring Gateway and check authentication?


The problem I am trying to solve is very common: (At Least i think so)

So far I have implemented two spring boot apps, the gateway service and the backend service, and run keycloak as OIDC-provider. So, the gateway is doing authentication per "authorization_code" and routs the user to a backend-endpoint. Backend is the resource-server and is checking the send JWT from Gateway for roles.

User<br>
  <space> |<br>
Gateway *(authentication against keycloak)*<br>
  / - \\<br>
UI  - Protected Resource/API Server *(Check the send JWT for roles)*

Everything is working fine!

Now I want to add an Angular frontend application.

And this application should also receive the JWT from the gateway and check if the user is authenticated.

My problem for now is that I can't find a good example how to configure the Angular app so that the routes in the app are secured and I can forward the token to the backend-Service.

Does anybody have an idea how to do this?

(Link would be fine)


Solution

  • What you are describing is gateway used as BFF (backend for front-end). That means that the gateway is the only OAuth2 client. This setup is used precisely to hide access-tokens from browser clients.

    In this configuration, Angular app is not OAuth2 at all. It won't retrieve tokens from the authorization-server (only gateway will), and it's request are authorized with a session on the Gateway not Bearer access-tokens.

    You could expose a user-info endpoint on your API. This is trivial to implement if all the info you need is contained in the access-token sent by gateway to Spring API: the resource-server could simply return the claims from the Jwt instance (principal in JwtAuthenticationToken, which is the default Authentication implementation for successful authorization in resource-servers):

    @GetMapping("/userinfo")
    @ResponseBody
    @PreAuthorise("isAuthenticated()") 
    public Map<String, Object> getUserinfo(JwtAuthenticationToken auth) {
        return auth.getClaims();
    }
    

    Complete tutorial there.

    Another option, as Keycloak is OpenID complient, would be to expose the ID-token on an API endpoint (or directly from the gateway which would be an OpenID client and have the ID-token for current user) and then decode this JWT in Angular app, but I do not have a simple solution in mind.