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

OAuth2 Password Flow modes do not match RFC #3227

Open
frol opened this issue Jun 10, 2017 · 11 comments
Open

OAuth2 Password Flow modes do not match RFC #3227

frol opened this issue Jun 10, 2017 · 11 comments

Comments

@frol
Copy link

frol commented Jun 10, 2017

Currently (Swagger UI master branch), only one out of three implemented OAuth2 Password Flow modes match RFC 6749 section 2.3.1, which explicitly states:

The authorization server MUST support the HTTP Basic authentication scheme for authenticating clients that were issued a client password.

For example (with extra line breaks for display purposes only):

      Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

Alternatively, the authorization server MAY support including the client credentials in the request-body using the following parameters:

client_id

REQUIRED. The client identifier issued to the client during the registration process described by Section 2.2.

client_secret

REQUIRED. The client secret. The client MAY omit the parameter if the client secret is an empty string.

Including the client credentials in the request-body using the two parameters is NOT RECOMMENDED and SHOULD be limited to clients unable to directly utilize the HTTP Basic authentication scheme (or other password-based HTTP authentication schemes). The parameters can only be transmitted in the request-body and MUST NOT be included in the request URI.

There are 3 modes implemented in Swagger UI for OAuth2 Password flow:

  1. "Request body" - Pass username with password in request-body and client_id with client_secret in "Authorization" header (Basic) - this is the CORRECT and RECOMMENDED way of doing this according to RFC.
  2. "Basic auth" - Pass username with password in "Authorization" header (Basic) with no client_id/client_secret - this has NOTHING TO DO with OAuth2 as far as I can tell, this is just someone's simplified authentication method. If there is no other place to implement this, well let it be there, but this might be a bit confusing.
  3. "Query parameters" - Pass username with password in request-body and client_id with client_secret in URI query encoded parameters - this is EXPLICITLY DISCOURAGED in the RFC since URLs are usually logged on the web servers and this would expose the plaintext secrets to anyone reading the logs.

The names in Swagger UI are completely misleading, by the way.

Here is my proposal:

  1. Rename "Basic auth" to "Basic username & password auth" to be more explicit, and move to the end of the list, though the only reason to leave it there is that there is no other place for it :(
  2. Rename "Request body" to "Basic auth" and leave it as default just as it is now.
  3. Replace "Query parameters" with new "Request body" and implement it so it passes client_id and client_secret via request-body.

/cc @bodnia @Naid405 @benoj @webron

@frol
Copy link
Author

frol commented Jun 10, 2017

Feel free to CC me to any OAuth2 related issues in Swagger UI in future. I might not help you with code, but I will at least try to help you with what RFC suggests to do.

@MugeSo
Copy link
Contributor

MugeSo commented Jul 21, 2017

This problem is based on the naming of list. It should be "clientAuthenticationType".

I'm very very disappointed because my implementation in #2397 is completely spoiled.

@krotscheck
Copy link

One additional note here- the Owner Credentials flow doesn't exclude public clients, in which case a client_id may be sent, but not have a corresponding client_secret. In that case, the method of attaching the client_id falls back to the last paragraph in section 3.2.1:

A client MAY use the "client_id" request parameter to identify itself when sending requests to the token endpoint.

@kopax
Copy link

kopax commented Nov 26, 2017

Hi, any update on this? I have played a bit with springfox and now I see it is not possible to pass a jwt to swagger-ui. Is a release scheduled at some point?

@krotscheck
Copy link

@kopax JWT's aren't part of the OAuth2 specification (RFC6749), except in the sense that the structure of the tokens is left to the implementation. Are you commenting on the correct issue?

@kopax
Copy link

kopax commented Nov 27, 2017

I have a *springboot backend secured with spring-security and spring-security-oauth2 and springfox installed. I am using the code grant flow specified in RFC6749.

I have a reactjs app as a client and I want to install swagger-ui on it.

I successfully managed to display the swagger-ui. The documentation says :

You can configure OAuth2 authorization by calling initOAuth method with passed configs under the instance of SwaggerUIBundle default client_id and client_secret, realm, an application name appName, scopeSeparator, additionalQueryStringParams, useBasicAuthenticationWithAccessCodeGrant.

The OAuth2 configuration explained in the documentation does not trigger any request to authenticate.

@krotscheck I am not sure if I am commenting the correct issue TBH, my issue I am in is more "Where is the swagger-ui OAuth documentation"...
I think you know how to help me out considering the change made in eebbfc4

This is how my react page look like :

import React from 'react';
import { SwaggerUIBundle, SwaggerUIStandalonePreset } from "swagger-ui-dist"
import 'swagger-ui-dist/swagger-ui.css';
import { oAuthClient } from "../../../config/index";
export default class SwaggerUIPage extends React.PureComponent {
  state = {
    ui: null,
  }
  componentDidMount() {
    this.initializeUi();
  }
  initializeUi() {
    const { redirectUri } = oAuthClient;
    const ui = SwaggerUIBundle({
      url: `http://localhost:8080/v2/api-docs`,
      dom_id: '#swagger-ui',
      oauth2RedirectUrl: 'http://localhost:8080/redirect/cb',
      presets: [
        SwaggerUIBundle.presets.apis,
        SwaggerUIStandalonePreset
      ],
      plugins: [
        SwaggerUIBundle.plugins.DownloadUrl,
        SwaggerUIBundle.plugins.AuthActions, // <-- Iam trying to add plugins in order to enable OAuth2 authentication
        SwaggerUIBundle.plugins.AuthIndex,
        SwaggerUIBundle.plugins.AuthReducers,
        SwaggerUIBundle.plugins.AuthSelectors,
        SwaggerUIBundle.plugins.AuthSpecWrapActions,
      ],
    });
    this.setState({ ui }, this.initializeOAuth);
  }

  initializeOAuth() {
    const { clientId, clientSecret, accessTokenUri, redirectUri } = oAuthClient;
    console.log(oAuthClient);
    console.log(SwaggerUIBundle.plugins);
    // Method can be called in any place after calling constructor SwaggerUIBundle
    const oauth = this.state.ui.initOAuth({
      clientId,
      clientSecret,
      realm: 'api',
      tokenUrl: 'http://localhost:8080/oauth/token',
      oauth2RedirectUrl: 'http://localhost:8080/redirect/cb',
      appName: 'reactapp',
      scopeSeparator: ' ',
      additionalQueryStringParams: { test: 'please help me login' },
      useBasicAuthenticationWithAccessCodeGrant: true,
      ...oAuthClient,
    });
    // console.log(window.opener.swaggerUIRedirectOauth2);
    // oauth2.callback({auth: oauth2.auth, token: json, isValid: true}) // <-- I have found that in the distributed oauth2 page html in the dist package, I have tried to called `oauth2.callback` myself but I can't get `window.opener.swaggerUIRedirectOauth2`
  }
  render = () => <div id="swagger-ui"/>
}
  1. How do you authenticate swagger-ui ?
  2. I can see sources that concern redux (login action/reducer) even If I don't see anywhere in the documentation where it says how to use it. Is there anything I a missing? Could you maybe share a more detailled example?

@krotscheck
Copy link

@kopax Ah, yes. In that case, you're definitely not commenting on the right issue. Github issues are more for bug reports and software design work, rather than integration help. For that, I would recommend the documentation and support resources- IRC, the website, etc.

Good luck!

@kopax
Copy link

kopax commented Nov 28, 2017

@krotscheck I really do understand and I've already been on IRC and the website before.
I've read the documentation and as explained in my post.

The documentation didn't helped me. I have opened #3953.

If you can give two minutes of your time to read the two questions, I'll appreciate. Good luck to you too!

krotscheck added a commit to krotscheck/swagger-ui that referenced this issue Feb 26, 2018
This pull request updates the "Password" flow to match the RFC, in
accordance to swagger-api#3227, with the following changes:
- Two methods have been explicitly removed (though names have been
  repurposed): Using login/pass in Basic Auth and including client_id
  and client_secret in the query string.
- The "Basic" auth method now uses the client_id and client_secret
  in the Authorization header, via Basic auth, in accordance with RFC
  section 2.3.1: https://tools.ietf.org/html/rfc6749#section-2.3.1
- The "Request Body" auth method now adds the client_id and the client_secret
  to the form body, in accordance to section 3.2.1: https://tools.ietf.org/html/rfc6749#section-3.2.1
- The form no longer hides the client_id or client_secret.

This is a breaking change, as the UI now responds differently to the values
set in the configuration file.
@Hronom
Copy link

Hronom commented Mar 11, 2018

Guys what the status of this? The password flow is unusable now.

This will very helpful for developers who use Spring Boot Security OAuth2.
It waits for:

  1. Parameters: client_id and client_secret in header Authorization:
 Authorization: Basic YnJvd3Nlcjo=
  1. Parameters: grant_type, scope, username and password in body of type:
content-type:"application/x-www-form-urlencoded"

Please fix this.

@Ciantic
Copy link

Ciantic commented Apr 8, 2018

I updated UI from 2.2.10 to 3.12.2 and the Password flow stopped working.

It authorizes normally, I can see from inspector, but the subsequent API requests does not send the "Authorization: Bearer ..." at all.

Is this related to this issue? It seemed to work fine with 2.x series.

@qcho
Copy link

qcho commented Oct 1, 2019

Any news on this issue?? It's really odd not not to be able to use the login as expected.

qcho added a commit to qcho/nerd that referenced this issue Oct 1, 2019
+    # TODO: Because SWAGGER-UI password-flow doesn't follow the oauth2 RFC it needs location='form' for it to work.
+    #       Rewrite is being discussed in swagger-api/swagger-ui#3227
+    #       https://www.oauth.com/oauth2-servers/access-tokens/password-grant/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants