Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I set route level "Bearer" Security in Swagger? #1089

Closed
cyantarek opened this issue Nov 26, 2019 · 10 comments
Closed

How can I set route level "Bearer" Security in Swagger? #1089

cyantarek opened this issue Nov 26, 2019 · 10 comments
Labels

Comments

@cyantarek
Copy link

cyantarek commented Nov 26, 2019

This is not a bug reports. But I find it little bit awkward to implement more Swagger features by digging into the Swagger proto files included with protoc-gen-swagger, as I could not find documentation on how to use more advanced features of swagger with grpc-gateway.

Anyway, after digging, much, I could not find any way to setup route level "Bearer" security.

Here's an example swagger.json file that has route level security setup.

   "/order/{order_id}": {
      "get": {
        "security": [
          {
            "Bearer": []
          }
        ],
    ...

With this, I can define which routes are public (JWT Bearer Token not required) or protected (JWT Bearer Token required).

How can I define this in proto so that protoc-gen-swagger can generate the swagger.json with the security option?

Thanks.

@johanbrandhorst
Copy link
Collaborator

Hi @cyantarek, thanks for the question. I thought we had an example for this, but it turns out we don't have one specifically for bearer auth, however, I know from experience that the following file-wide configuration should work:

option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
  security_definitions: {
    security: {
      key: "bearer"
      value: {
        type: TYPE_API_KEY
        in: IN_HEADER
        name: "Authorization"
        description: "Authentication token, prefixed by Bearer: Bearer <token>"
      }
    }
  }
  security: {
    security_requirement: {
      key: "bearer"
    }
  }
};

This enables in-header authentication on all routes, and you can overwrite it for a specific route like so (I think, untested):

  rpc CreateUser(CreateUserRequest) returns (User) {
    option (google.api.http) = {
      post: "/api/v1/user"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
      security: { } // Disable security key
    };
  }

I don't think there's anyway to force the user to specify the Bearer prefix with openapi 2, so this may be the closest you will get. If this helped you, would you be interested in contributing this to our documentation?

@cyantarek
Copy link
Author

Hi,

Thanks for the info.

I'm working on the grpc gateway swagger in one of my projects. And yeah, I want to make a documentation how I'm doing. Can you please tell me where can I put the README.md file?

@johanbrandhorst
Copy link
Collaborator

This sort of thing could go in https://github.com/grpc-ecosystem/grpc-gateway/blob/master/docs/_docs/customizingyourgateway.md, or maybe a new file. You can see what these files look like right now here: https://grpc-ecosystem.github.io/grpc-gateway/docs/customizingyourgateway.html

@cyantarek
Copy link
Author

cyantarek commented Nov 26, 2019

After following your this recipe:

 rpc CreateUser(CreateUserRequest) returns (User) {
    option (google.api.http) = {
      post: "/api/v1/user"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
      security: { } // Disable security key
    };
  }

I'm getting this error
Option field "(grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger)" is not a field or extension of message "MethodOptions"

May be I need to use this:

grpc.gateway.protoc_gen_swagger.options.openapiv2_operation

@johanbrandhorst
Copy link
Collaborator

Yeah, you're right, change grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger to grpc.gateway.protoc_gen_swagger.options.openapiv2_operation. Does that work?

@cyantarek
Copy link
Author

Yeah, that works great. Thanks!

@johanbrandhorst
Copy link
Collaborator

That's great! Would you be willing to add some docs around this in a PR?

@cyantarek
Copy link
Author

Sure, I'll add very soon!

@stale
Copy link

stale bot commented Jan 26, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@ganttee
Copy link

ganttee commented Jan 23, 2024

The above usage test failed, and the latest one has become:

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
    security_definitions: {
      security: {
        key: "bearer"
        value: {
          type: TYPE_API_KEY
          in: IN_HEADER
          name: "Authorization"
          description: "Authentication token, prefixed by Bearer: Bearer <token>"
        }
      }
    }
    security: {
      security_requirement: {
        key: "bearer"
      }
    }
};
rpc CreateUser(CreateUserRequest) returns (User) {
    option (google.api.http) = {
      post: "/api/v1/user"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      security: { } // Disable security key
    };
  }

vroldanbet added a commit to authzed/api that referenced this issue Nov 11, 2024
SpiceDB does not use ApiKeyAuth authentication, but Bearer authentication, where
the type of bearer token is an API Key.

However, the OpenAPI v2 Spec, which is the one supported by grpc-gateway,
does not support bearer authentication:
https://swagger.io/docs/specification/v2_0/authentication/authentication/

Still, the grpc-gateway maintainers indicated in
grpc-ecosystem/grpc-gateway#1089
that bearer is actually supported in grpc-gateway generator.

This was reported in authzed/authzed-go#255,
indicating that folks generating code out of the OpenAPI definition
will have errors because the generated error did not properly provide
the preshared key with the expected `Authorization: Bearer <psk>`
format.

I'm not 100% sure if this is a legit intermediate state
between v2 and v3 we can leverage, but the current generated
code is clearly broken anyway.

See https://swagger.io/docs/specification/v3_0/authentication/api-keys/
See https://swagger.io/docs/specification/v3_0/authentication/bearer-authentication/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants