**Prerequisite**

I'm using Spring Security to authenticate my users with firebase. During authentication I also extract the users roles from the JWT token and convert them into `SimpleGrantedAuthorities`.

In most cases I can use `@PreAuthorize("hasRole('ROLE_ADMIN')")` to apply authorization to an endpoint. But now I have a more complex authorization scenario.

I have a `Service` that fetches a `Product`, but only users who have purchased the product are allowed to receive it.

```kotlin
fun fetchProduct(val id: Int, userId: String) {
  val product = productRepository.findById(id)

  // only users that purchased the product are allowed to fetch it!
  if (!product.isAccessibleAtNoCharge(userId) && !purchaseCheck.hasUserPurchased(userId, product.id)) {
    throw ForbiddenException("User has not purchased product")
  }
  return product
}

```

**What I want to achieve**

My requirement is, that users with the role `ROLE_ADMIN` can bypass that check, so that they can access products without purchasing them before.

**What I have tried**

My only idea so far is to retrieve the roles from `SecurityContext` like so:

```kotlin
fun fetchProduct(val id: Int, userId: String) {
  val product = productRepository.findById(id)

  val isAdmin = SecurityContextHolder.getContext().authentication.authorities.any { it.authority == "ROLE_ADMIN" }
  if(isAdmin) {
    return product
  } else {
    // check if purchased
    ...
  }  
}

```

**Considerations**

* I have doubts that this solution is well testable, because of the static method call
* I feel that the solution is not abstracted (mixing business logic and authorization logic)
* Usually authorization seems to be done in the controller, which is not possible in this case?

Do you have suggestions for alternative solutions?