You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Alexander K. (JIRA)" <ji...@apache.org> on 2016/11/17 08:11:58 UTC

[jira] [Comment Edited] (CXF-7137) Allow OAuth2 customization via Swagger2Feature

    [ https://issues.apache.org/jira/browse/CXF-7137?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15673099#comment-15673099 ] 

Alexander K. edited comment on CXF-7137 at 11/17/16 8:11 AM:
-------------------------------------------------------------

Hi, according to OAuth2 spec, there are 3 ways for client's authentication: confidential, public and bearer-only.
- Confidential clients require a secret to initiate login protocol.
- Public clients do not require a secret to initiate login protocol.
- Bearer-only clients are web services that never initiate a login (user must be already authenticated).

So the protected web services are bearer-only clients and this means that Swagger API Docs are read only because clicking on "Try it out!" button will return an error saying "This request requires HTTP authentication."
This is fine unless you would like to allow the "Try it out!" option for test purposes only. And this is our part.
Swagger-UI supports the OAuth2 spec by providing an option to configure the required parameters. It is possible to define via Swagger annotations SecurityDefinition as part of SwaggerDefinition annotation, but it does not work because SwaggerDefinition annotation is ignored when using Swagger2Feature (it is a separate issue). So I found references that provide a workaround by overriding Swagger2Feature.addSwaggerResource() method:

  super.addSwaggerResource(server, bus);
  BeanConfig scanner = (BeanConfig) ScannerFactory.getScanner();
  Swagger swagger = scanner.getSwagger();
  swagger.securityDefinition("qa-auth", new OAuth2Definition().implicit("http://localhost:8080/auth/realms/master/protocol/openid-connect/auth").scope("qa", "test"));

Once SecurityDefinition is defined, Swagger shows "Authorize" button in upper right corner near "Explore" button which allows manual authorization by redirecting to an authorization server's login page (Keycloak in my case). After the manual authorization (login) the user should be able to try out the protected services because Swagger-UI will receive a token from the authorization server as part of authorization process. Of course the Swagger-UI must be defined in the authorization server as a public or confidential client and according to this the oauth parameters should be defined.
So, as you can see, the web services and Swagger clients are separated clients and have different authentication types. Swagger allows access to web services but only for eligible persons and for testing purposes only (since in the authentication server you can even assign a client to a specific scope).

Now, the problem is that Swagger-UI generates URI to call authorization server with incorrect parameters which are hard-coded in the HTML file (realm=your-realms, client_id=your-client-id, etc):
http://localhost:8080/auth/realms/master/protocol/openid-connect/auth?response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fservices%2Fo2c.html&realm=your-realms&client_id=your-client-id&scope=qa

As an example, you can see that Swashbuckle (.Net project for Swagger) allows this configuration by its own syntax like this:
EnableSwaggerUi(c => { c.EnableOAuth2Support("test-client-id", "test-realm", "Swagger UI"); })

Hopefully it was clear :)
Thanks


was (Author: alexkra@amdocs.com):
Hi, according to OAuth2 spec, there are 3 ways for client's authentication: confidential, public and bearer-only.
- Confidential clients require a secret to initiate login protocol.
- Public clients do not require a secret to initiate login protocol.
- Bearer-only clients are web services that never initiate a login (user must be already authenticated).
So the protected web services are bearer-only clients and this means that Swagger API Docs are read only because clicking on "Try it out!" button will return an error saying "This request requires HTTP authentication."
This is fine unless you would like to allow the "Try it out!" option for test purposes only. And this is our part.
Swagger-UI supports the OAuth2 spec by providing an option to configure the required parameters. It is possible to define via Swagger annotations SecurityDefinition as part of SwaggerDefinition annotation, but it does not work because SwaggerDefinition annotation is ignored when using Swagger2Feature (it is a separate issue). So I found references that provide a workaround by overriding Swagger2Feature.addSwaggerResource() method:

  super.addSwaggerResource(server, bus);
  BeanConfig scanner = (BeanConfig) ScannerFactory.getScanner();
  Swagger swagger = scanner.getSwagger();
  swagger.securityDefinition("qa-auth", new OAuth2Definition().implicit("http://localhost:8080/auth/realms/master/protocol/openid-connect/auth").scope("qa", "test"));

Once SecurityDefinition is defined, Swagger shows "Authorize" button in upper right corner near "Explore" button which allows manual authorization by redirecting to an authorization server's login page (Keycloak in my case). After the manual authorization (login) the user should be able to try out the protected services because Swagger-UI will receive a token from the authorization server as part of authorization process. Of course the Swagger-UI must be defined in the authorization server as a public or confidential client and according to this the oauth parameters should be defined.
So, as you can see, the web services and Swagger clients are separated clients and have different authentication types. Swagger allows access to web services but only for eligible persons and for testing purposes only (since in the authentication server you can even assign a client to a specific scope).

Now, the problem is that Swagger-UI generates URI to call authorization server with incorrect parameters which are hard-coded in the HTML file (realm=your-realms, client_id=your-client-id, etc):
http://localhost:8080/auth/realms/master/protocol/openid-connect/auth?response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fservices%2Fo2c.html&realm=your-realms&client_id=your-client-id&scope=qa

As an example, you can see that Swashbuckle (.Net project for Swagger) allows this configuration by its own syntax like this:
EnableSwaggerUi(c => { c.EnableOAuth2Support("test-client-id", "test-realm", "Swagger UI"); })

Hopefully it was clear :)
Thanks

> Allow OAuth2 customization via Swagger2Feature
> ----------------------------------------------
>
>                 Key: CXF-7137
>                 URL: https://issues.apache.org/jira/browse/CXF-7137
>             Project: CXF
>          Issue Type: Improvement
>          Components: JAX-RS
>    Affects Versions: 3.1.8
>            Reporter: Alexander K.
>
> It seems that there is no way to customize initOAuth() details like clientId, clientSecret, realm, appName, etc. for SwaggerUI-OAuth integration. This will allow Swagger-UI authorization for protected CXF REST services by an authorization server such as Keycloak.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)