title: Spring Cloud Gateway to enhance JWT tokens from external OAuth Authorization Server
body: <p>I have the following <a href="https://spring.io/blog/2019/08/16/securing-services-with-spring-cloud-gateway" rel="nofollow noreferrer">Securing Services with Spring Cloud Gateway</a> working with Keycloak. Expanding upon this I am routing to many Webflux Resources Servers.</p>
  
  <p>However, the scopes provided by external Authorization servers are very simplistic. So I need to take the micro-service ID plus the User ID from the JWT and then check a database which then translates to their Team, which would then provide a list of accessible static pages and URL REST endpoints. So my resulting code would like something like;</p>
  
  <pre><code>...
    .matcher("/page1.html").hasAuthority("SERVICE1_PAGE1")
    .matcher("/page2.html").hasAuthority("SERVICE1_PAGE2")
  
  
  @PreXXX("hasAuthority('SERVICE1_getAll'))
  public List&lt;String&gt; getAll() {...}
  </code></pre>
  
  <p>I assume that I could do it at the micro-service level by <a href="https://docs.spring.io/spring-security/site/docs/5.2.0.RELEASE/reference/htmlsingle/#oauth2resourceserver-jwt-authorization-extraction" rel="nofollow noreferrer">Extracting Authorities Manually</a>, but by doing this I would need to duplicate this code in every micro-service. </p>
  
  <p><strong><em>Edit:</em></strong> This is what I am currently doing, by using a <code>WebClient</code> to call another common micro-service which returns the corrected authorities. However, if the URL of the authority micro-service is a Gateway address, the Gateway never attempts to resolve the URL. If I use it's explicit URL, I get 401 from the authority micro-service, even though I use <code>ServerBearerExchangeFilterFunction</code>. If I put <code>permitAll()</code> on the micro-service which returns the authorities, it works.</p>
  
  <p>I could stand up my own Authorization server and use a <code>TokenEnhancer</code>. However, by doing so, I assume that I would need to load up all possible permissions for the user for every possible micro-service (as I do not know at this point where the user is going) and could result in a lot of data.</p>
  
  <p>Ideally, I would like to centralise this in the Gateway and have the <code>TokenRelay</code> filter recognise the route and somehow enhance the token. Is this possible?</p>
  
  <p>Can someone please recommend how best to go about this?</p>