Vertx + OpenAPI + OAuth2安全处理程序正在调用两次

时间:2018-01-12 05:21:57

标签: oauth-2.0 vert.x openapi

我是vertx世界的新手。我使用此链接设置我的openapi路由:https://gist.github.com/slinkydeveloper/bdf5929c2506988d78fc08205089409a

以下是我的消息来源:

api.yaml

#other endpoints...
/api/v1/protected/verification:
post:
  summary: Summary
  operationId: verification
  security:
    - ApiKey: []
  tags:
    - verification
  responses:
    '200':
      description: User details
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/User"
    '401':
      description: Unauthorized

    default:
      description: unexpected error
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Exception"
#other endpoints ....
components:
  securitySchemes:
   ApiKey:
    type: apiKey
    name: Authorization
    in: header
#other ones

OpenApi设置

OpenAPI3RouterFactory.createRouterFactoryFromFile(vertx, "src/main/resources/api.yaml") { openAPI3RouterFactoryAsyncResult ->
        if (openAPI3RouterFactoryAsyncResult.succeeded()) {
            // Spec loaded with success
            val routerFactory = openAPI3RouterFactoryAsyncResult.result()
            val keycloakJson = JsonObject("{\n" +
                    "\"realm\": \"master\",\n" +
                    "\"bearer-only\": true,\n" +
                    "\"auth-server-url\": \"http://localhost:8080/auth\",\n" +
                    "\"ssl-required\": \"external\",\n" +
                    "\"realm-public-key\": \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn9Xya697ZVZzQidld4uCwRoWmLyWBDQQhn+EL1e0WDUWq9v39OBpM+HadkYlOMvfU1A8ohGZZVBkKV4w35gkm3bFPluCPsWxdcqD1NNF6BnIC6bRicgP/4beeehff8nWI3mFAfH7Q7Ik8mm8BDQYhOPRx50JBkDiIQ7AlAjNJ+5/eIj6Pt/eZSmMSk+vM4Xu64E0mCZfHpasdf!QsFGN+VPQejNBz7h9nEdi3swIIo0ot2+5PZGELX/2Dek7cY4RMKGb+rvU6ug3UvZHQ985KuubKsWMCs8+A80yWSoA6umw1DC5rAmc5jo/6giWawuFj5jFZRx69CcMSx1VaEJ5lS4LmAi5sXuQIDAQAB\",\n" +
                    "\"resource\": \"vertx\",\n" +
                    "\"use-resource-role-mappings\": true,\n" +
                    "\"credentials\": {\n" +
                    "\"secret\": \"asd1t747-3d11-456f-a553-d8e140cfaf58\"\n" +
                    "}\n" +
                    "}")
            val oauth2 = KeycloakAuth
                    .create(vertx, OAuth2FlowType.AUTH_CODE, keycloakJson)
            val handler = OAuth2AuthHandler.create(oauth2,
                    "http://localhost:8081/")
            routerFactory.addSecurityHandler("ApiKey", handler)

            handler?.setupCallback(routerFactory.router.route("/callback"))

            routerFactory.addHandlerByOperationId(EndpointUriOperationId.SIGN_UP.endpoint, { routingContext -> signUpRouter?.signUp(routingContext) })
            routerFactory.addHandlerByOperationId(EndpointUriOperationId.SIGN_IN.endpoint, { routingContext -> signInRouter?.signIn(routingContext) })
            routerFactory.addHandlerByOperationId(EndpointUriOperationId.CONFIRM_ACCESS_CODE.endpoint, { routingContext -> signUpRouter?.confirmAccessCode(routingContext) })
            routerFactory.addHandlerByOperationId(EndpointUriOperationId.IS_EMAIL_EXISTS.endpoint, { routingContext -> signUpRouter?.isEmailExists(routingContext) })
            routerFactory.addHandlerByOperationId(EndpointUriOperationId.GET_ACCESS_CODE.endpoint, { routingContext -> signUpRouter?.getAccessCode(routingContext) })
            routerFactory.addHandlerByOperationId(EndpointUriOperationId.VERIFICATION.endpoint, { routingContext -> signInRouter?.verification(routingContext) })

            // Add an handler with a combination of HttpMethod and path
            // Before router creation you can enable or disable mounting a default failure handler for ValidationException

            // Now you have to generate the router

            val router = routerFactory.router
            router.route().handler(CorsHandler.create("*")
                    .allowedMethod(HttpMethod.GET)
                    .allowedMethod(HttpMethod.DELETE)
                    .allowedMethod(HttpMethod.POST)
                    .allowedMethod(HttpMethod.PUT)
                    .allowedMethod(HttpMethod.PATCH)
                    .allowedHeader("Authorization")
                    .allowedHeader("user-agent")
                    .allowedHeader("Access-Control-Request-Method")
                    .allowedHeader("Access-Control-Allow-Credentials")
                    .allowedHeader("Access-Control-Allow-Origin")
                    .allowedHeader("Access-Control-Allow-Headers")
                    .allowedHeader("Content-Type")
                    .allowedHeader("Content-Length")
                    .allowedHeader("X-Requested-With")
                    .allowedHeader("x-auth-token")
                    .allowedHeader("Location")
                    .exposedHeader("Location")
                    .exposedHeader("Content-Type")
                    .exposedHeader("Content-Length")
                    .exposedHeader("ETag")
                    .maxAgeSeconds(60))
            // Now you can use your Router instance
            val server = vertx.createHttpServer(HttpServerOptions().setPort(8081).setHost("0.0.0.0"))
            server.requestHandler(router::accept).listen()
            print("server is run\n")
        } else {
            // Something went wrong during router factory initialization
            val exception = openAPI3RouterFactoryAsyncResult.cause()
            print("OpenApiRoutingError! $exception")
        }
    }

我的验证端点

fun verification(routingContext: RoutingContext) {
    val map = (routingContext.user() as AccessTokenImpl).accessToken().map
    val username = map.get("preferred_username").toString()
    vertx.eventBus().send(SignInHandlerChannel.VERIFICATION.value(), username, { reply: AsyncResult<Message<String>> ->
        if (reply.succeeded()) {
            val result = JsonUtils.toPojo<MultiPosResponse<VerificationMapper>>(reply.result().body().toString())
            routingContext
                    .response()
                    .putBrowserHeaders()
                    .setStatusCode(result.code!!)
                    .end(result.toJson())
        } else{
            routingContext
                    .response()
                    .putBrowserHeaders()
                    .setStatusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code())
                    .end(reply.cause().toString())
        }
    })
}

问题是当我向“/ api / v1 / protected / verification”端点发送请求时,我的oauth2处理程序工作两次。首先通过oauth处理程序请求进程(必须)然后传递给next到我的端点处理程序,之后由于某种原因请求再次传递给oauth2处理程序(我认为它不应该是)。我该如何解决这个问题?

0 个答案:

没有答案