imposter icon indicating copy to clipboard operation
imposter copied to clipboard

[QUESTION] Configuration example for providing security config for individual plugins and swagger UI

Open mkalish opened this issue 1 year ago • 2 comments

This is really two questions, please let me know if this is better off being split into two issues.

The first question is if it possible to configure security for two different configured OpenAPI specs

Config 1

---
plugin: openapi
specFile: pestore1.yaml


 security:
    default: Deny
    conditions:
    - effect: Permit
      requestHeaders:
        client_id: client
        client_secret: secret

Config 2

---
plugin: openapi
specFile: pestore2.yaml


 security:
    default: Deny
    conditions:
    - effect: Permit
      requestHeaders:
        client_id: client
        client_secret: differentSecret

This generates the following error:

2024-05-29 10:39:56 java.lang.IllegalStateException: Cannot specify root 'security' configuration block more than once. Ensure only one configuration file contains the root 'security' block.
2024-05-29 10:39:56     at io.gatehill.imposter.service.security.SecurityServiceImpl.findConfigPreferringSecurityPolicy(SecurityServiceImpl.kt:93) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at io.gatehill.imposter.service.HandlerServiceImpl.build(HandlerServiceImpl.kt:100) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at io.gatehill.imposter.Imposter.configureRoutes$lambda$8(Imposter.kt:202) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at io.gatehill.imposter.util.MetricsUtil.doIfMetricsEnabled(MetricsUtil.kt:74) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at io.gatehill.imposter.Imposter.configureRoutes(Imposter.kt:199) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at io.gatehill.imposter.Imposter.access$configureRoutes(Imposter.kt:88) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at io.gatehill.imposter.Imposter$start$1.invokeSuspend(Imposter.kt:135) ~[imposter-engine-3.38.3.jar:?]
2024-05-29 10:39:56     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) ~[kotlin-stdlib-1.9.10.jar:1.9.10-release-459]
2024-05-29 10:39:56     at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) ~[kotlinx-coroutines-core-jvm-1.7.3.jar:?]
2024-05-29 10:39:56     at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) ~[kotlinx-coroutines-core-jvm-1.7.3.jar:?]
2024-05-29 10:39:56     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793) ~[kotlinx-coroutines-core-jvm-1.7.3.jar:?]
2024-05-29 10:39:56     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697) ~[kotlinx-coroutines-core-jvm-1.7.3.jar:?]
2024-05-29 10:39:56     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684) ~[kotlinx-coroutines-core-jvm-1.7.3.jar:?]

A related question is how to configure just a single security block, but still allow the Swagger UI to work as expected? Config:

---
plugin: openapi
specFile: pestore.yaml


 security:
    default: Deny
    conditions:
    - effect: Permit
      requestHeaders:
        client_id: client
        client_secret: secret
Screenshot 2024-05-29 at 1 29 03 PM

mkalish avatar May 29 '24 14:05 mkalish

Hi @mkalish, thank you for raising this.

On the second part of your question, regarding allowing Swagger UI to work, something like this should work:

---
plugin: openapi
specFile: petstore.yaml

resources:
  # always permit spec endpoint
  - path: /_spec/*
    security:
      default: Allow

# ... other config

outofcoffee avatar Jul 01 '24 10:07 outofcoffee

To apply different config to different paths, such as from different OpenAPI specs, you could use interceptors.

Something like this could work:

plugin: openapi
specFile: petstore.yaml

interceptors:
# rules for first set of paths
- path: /base-path-for-some-spec
  requestHeaders:
    client_id:
      value: client
      operator: NotEqualTo
    client_secret:
      value: client_secret
      operator: NotEqualTo
  response:
    statusCode: 401

# rules for second set of paths
- path: /base-path-for-different-spec
  requestHeaders:
    client_id:
      value: different_client
      operator: NotEqualTo
    client_secret:
      value: different_client_secret
      operator: NotEqualTo
  response:
    statusCode: 401

outofcoffee avatar Jul 01 '24 10:07 outofcoffee