Spring Boot + KC Adapter + SCOPE mapping

Hello,
I’m using spring boot 2.2.x + keycloak adapter 9.0.0.
I’m wondering whether it is possible to map keycloak client’s scope to spring security.
So for example if I want to use something like @PreAuthorize("hasAuthority('SCOPE_message:read')") how can this be done with keycloak spring-boot adapter? Currently only user roles are mapped, client scopes are omitted.
I know how to do that without adapter using jwt token mapper, but I’m trying to use adapter for first time and I didn’t found the way how to do that.

Thanks

1 Like

I use Spring Boot and leverage Spring Security’s support for OAuth 2.0 and Jason Web Tokens (JWTs). For example:

package org.serendipity.restapi.controller;

import org.serendipity.restapi.hateoas.IndividualRepresentationModelAssembler;
import org.serendipity.restapi.model.Individual;
import org.serendipity.restapi.service.IndividualService;

import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.server.ResponseStatusException;

@BasePathAwareController
public class IndividualController {

  private final IndividualRepresentationModelAssembler assembler;
  private final IndividualService entityService;

  public IndividualController(IndividualService entityService,
                              IndividualRepresentationModelAssembler assembler) {

    this.entityService = entityService;
    this.assembler = assembler;
  }
  
  @GetMapping("/whoami")
  public String whoami(@AuthenticationPrincipal Jwt jwt) {
    return String.format("Hello, %s!", jwt.getSubject());
  }
  
  @GetMapping("/individuals")
  @PreAuthorize("hasAuthority('SCOPE_individual:read')")
  public ResponseEntity<CollectionModel<EntityModel<Individual>>> findAll() {
    
    return ResponseEntity.ok(assembler.toCollectionModel(entityService.findAll()));
  }
  
  @GetMapping("/individuals/{id}")
  @PreAuthorize("hasAuthority('SCOPE_individual:read')")
  public ResponseEntity<EntityModel<Individual>> findById(
      @PathVariable("id") final Long id) throws ResponseStatusException {
    
    Individual entity = entityService.findById(id).orElseThrow(() -> 
        new ResponseStatusException(HttpStatus.NOT_FOUND));
    
    return ResponseEntity.ok(assembler.toModel(entity));
  }
  
}

Ref: Flowable OAuth2 Resource Server

Well, you are not using keycloak adapter are you? That looks like spring customised configuration.

@bilak, did you find a solution?