I'm running into an issue with the spec.
https://github.com/swagger-api/validator-badge/issues/73
It seems that template paths are not allowed in the tokenUrl parameter of security definitions.
my use case is:
securityDefinitions:
oauth2PasswordSecurity:
type: oauth2
flow: password
tokenUrl: 'https://example.com/V2/user/{user_id}/oauth/token'
I'm not sure if it's a bug in the 2.0 spec or a feature for next version.
What would be the best way to deterministically describe template paths to clients ?
tokenUrl is type string and format uri why does format uri not support RFC 6570 URI Template ?
URI Template strings themselves are not valid URIs _(strictly)_. Some of the characters used in URI Templates are special characters in the URI specification and require being escaped. The reason the paths keys are allowed to use { and } without issue is because it does not use the uri format: https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json#L173
There are a number of other places in the issue tracker where tokenization of the Swagger specification is being requested so don't take my explaining _"why"_ as us not being willing to support it.
@deefactorial - the real question here is - do you just want to describe it as a templated path? If so, you can easily do so by escaping the URL according to the regular URI escaping rules.
If you expect an added functionality, such that the user should be able to specify the value for the templated path, then it would be a feature request for the next version. I've never really seen before the example where an OAuth2 token URL is personalized to the user - normally there's one end point for such requests. If you could provide more details as to why you chose to implement it this way (as it seems uncommon), it would help us in assessing it for the future. Of course, it could be a very common practice which I'm not aware of, and in that case I'd ask to see some references to usage out there or references to public documentation suggesting this form of implementation.
I understand that this is uncommon way of describing this particular end point. Since working with swagger to define my API I have re-factored the way I describe my end points. I find the easiest way to explain my model is to push primary key data into the path. the 'user_id' in my example is just one of those primary key data elements that needs to be known prior to posting to the API end point. without that information you can't post to the end point. It's more of a convention I use for my API.
I think the best way for me to write this in my API is to escape the template path and provide a vendor extension pointer to the operation id of the oauth end point in my API.
Something like this:
securityDefinitions:
oauth2PasswordSecurity:
type: oauth2
flow: password
tokenUrl: 'https://example.com/V2/user/%7Buser_id%7D/oauth/token'
x-token-operation-id: oauth2tokenPost
With this I have a valid swagger definition, and if clients want more information on how to use the end point they can reference the operation id.
Right, though that takes away from the ability to automate the process easily. Still doable, but just not as easy. However, there are so many design options out there...
I'm not sure if it would make sense to support it in the next version, but I'll mark it up for discussion.
Parent issue #585
I think doing password flow to obtain tokens this way is fairly unusual. Considering the additional complexity introduced by templating URLs, I don't think we can address this in 3.0.
Btw, templates do not work in server part of relative tokenUrl either.
For example
servers:
- url: https://{customer}.example.com
variables:
customer:
default: demo
...
securitySchemes:
Oauth2:
type: oauth2
flows:
clientCredentials:
tokenUrl: /token
scopes: {}
resolves to token url 'https://%7Bcustomer%7D.example.com/token'.
@deus-x-machina that sounds like an issue with the specific tool you're using - not the spec.
We have a system with a perimeter server, which passes requests to a farm of back-end servers. Each back-end server belongs to a specific tenant, and in the API we add the tenant name to the URLs in order to know which back-end to send the request to. In this scenario, we would like to also pass the authentication request on to the correct back-end system. I.e., the URL would look like
tokenUrl: https://www.frontend.com/{tenant}/token
So in this scenario I don't find it odd to have a parameter in the tokenUrl. I really hope this feature will be added.
This is a requirement for me for Keycloak multi-tenancy using realms. But also the keycloak server is different than the application server (we are using Kubernetes ingress host based routing).
So, I need similar functionality to the OpenAPI servers section.
For example, I need to parameterize the tokenURL like this:
securitySchemes:
keycloak:
type: oauth2
description: This API uses OAuth 2
flows:
clientCredentials:
tokenUrl: {protocol}://{server}:{port}/auth/realms/{realm}/protocol/openid-connect/token
variables:
protocol:
enum:
- 'http'
- 'https'
default: 'http'
server:
default: 'keycloak.company.com'
port:
enum:
- '80'
- '443'
default: '80'
realm:
default: 'myTenant'
scopes: {}
Btw, templates do not work in server part of relative tokenUrl either.
For example
servers: - url: https://{customer}.example.com variables: customer: default: demo ... securitySchemes: Oauth2: type: oauth2 flows: clientCredentials: tokenUrl: /token scopes: {}resolves to token url 'https://%7Bcustomer%7D.example.com/token'.
Is there any way to read the template varaible in the client auth pop up window? With the swagger-ui-dist NPM module this is not reading the variable defined in the servers url and its creating trouble for us too
@rupamkhaitan Swagger UI issue that you mentioned is tracked here: https://github.com/swagger-api/swagger-ui/issues/4740
I posted this question on SO a while back -
Good to see other people are thinking about something similar.
One thing to keep in mind regarding the server templating;
if you're using an external IDP (e.g. Auth0, Okta, etc), the IDP base URL would not be the same as the service/endpoint base URLs... this has implications for using the existing servers element, which is already used for templating of the service/endpoint base URLs...
Most helpful comment
@rupamkhaitan Swagger UI issue that you mentioned is tracked here: https://github.com/swagger-api/swagger-ui/issues/4740