Implementing OAuth2's Authorization Code Grant flow type with Swagger

3,491 views
Skip to first unread message

Candide Kemmler

unread,
May 2, 2014, 7:45:22 AM5/2/14
to swagger-sw...@googlegroups.com, Anne Wright
Hi,

Thank you for developing an awesome documentation generation tool. I was successful in generating basic information for our API. The next step for me is to get the "Try it out" button to work. The problem is I don't quite yet understand how the different pieces fit together. I have a working oauth2 provider implemented with Apache OLTU, so I tried to configure Swagger with the endpoints that I have defined there. I'm doing this in a Bootstrap servlet as you are doing in one of your examples. I have also included the following jars in my project's pom:

        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-core_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-oauth2-server_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
            <version>1.3.5</version>
        </dependency>

When I load swagger-ui, I get the following JSON from my api-docs endpoint:

{
"apiVersion": "",
"swaggerVersion": "1.2",
"apis": [{
"path": "/connectors",
"description": "Connector and connector settings management operations (list, add, remove, etc.)"
}, {
"path": "/metadata",
"description": "Location/Timezone query and disambiguation endpoints."
}, {
"path": "/calendar",
"description": "Main devices and service API facets consumption operations"
}],
"authorizations": {
"oauth2": {
"type": "oauth2",
"scopes": [],
"grantTypes": {
"authorization_code": {
"tokenRequestEndpoint": {
"clientIdName": "client_id",
"clientSecretName": "client_secret"
},
"tokenEndpoint": {
"tokenName": "access_code"
}
}
}
}
},
"info": {
"title": "Fluxtream Public REST API",
"description": "",
"contact": "info-at-fluxtream.org",
"license": "Apache 2.0",
}

I have also decorated some of our Jersey enabled classes with, e.g.:
@Api(value = "/connectors", description = "Connector and connector settings management operations (list, add, remove, etc.)",
        authorizations = {@Authorization(value="oauth2")})
and methods with e.g.
    @ApiOperation(value = "Reset connector settings to their default values", response = StatusModel.class,
                  notes="A set of default values are stored alongside user modified values for all connector settings",
                  authorizations = {@Authorization(value="oauth2")})


Now I was expecting that swagger ui would use that info to point me to some url in order to initiate the oauth dance and somehow do the necessary steps in order to acquire an access token but I wasn't able to test that as, while I do notice a little "on/off" switch next to the docs of my auth-enabled API methods, there is also a little red exclamation mark next to it and clicking on the switch does nothing.

Also, I am confused by looking at the source code in swagger core's oauth2-auth-server module where you apparently provide your own implementation of an oauth2 provider. Does it mean that the authorization annotations for the API only work with this implementation?

For the record, here's my attempt at providing Swagger with working oauth2 configuration values: SwaggerBootstrapServlet
And here is a Jersey enabled class annotated with Swagger: ConnectorStore

Your help will be very much appreciated!

Thank you again for an awesome tool,

Best regards,

Candide

tony tam

unread,
May 2, 2014, 4:58:52 PM5/2/14
to swagger-sw...@googlegroups.com, Anne Wright
Hi,
You actually don't need the oauth2 server UNLESS you're using our implementation to make an actual oauth2 provider.  Since you're (also) using OLTU, you can remove that dependency.

Take a look at petstore.swagger.wordnik.com and look at the POST operation for the pet resource.  Clicking that will do a couple things:

1) pop-up a dialog box showing the scopes that are defined in your resource listing, allowing the user to select them
2) redirect the user to the URL defined in the resource listing.

Note that in your index.html you'll need to enable the JS at the top:

<script src='lib/swagger-oauth.js' type='text/javascript'></script>

You also need to initialze the configuration:

        if(typeof initOAuth == "function") {
          initOAuth({
            clientId: "your-client-id",
            realm: "your-realms",
            appName: "your-app-name"
          });
        }

See if that helps, and jump in the IRC channel if you need help.

Candide Kemmler

unread,
May 2, 2014, 5:15:41 PM5/2/14
to swagger-sw...@googlegroups.com, Anne Wright
Hi Tony,

Thanks for the unneeded oauth server dependency - I was obviously confused. I had the other pieces right. The one remaining stumbling point is the realm property... We don't really implement realms but I can indeed see that swagger is missing a value there as it's saying:

Array[1]
  1. 0"auth unable initialize oauth: missing realm"
  2. length1

Before I jump to IRC, is there some default value I could use?

Thanks again for your help!

Candide

--
You received this message because you are subscribed to a topic in the Google Groups "Swagger" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/swagger-swaggersocket/_g1xPpkwHho/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

tony tam

unread,
May 2, 2014, 5:17:12 PM5/2/14
to swagger-sw...@googlegroups.com, Anne Wright
That would be a bug in the implementation.  If should be optional--put anything and let's see what happens.
To unsubscribe from this group and all its topics, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Candide Kemmler

unread,
May 2, 2014, 5:25:32 PM5/2/14
to swagger-sw...@googlegroups.com, tony tam, Anne Wright
Ah! Doing progress, now clicking on the switch triggers the following dialog:


But clicking on Authorize tries to fetch an inexistant document

Not Found

The requested URL /swagger-ui/null&redirect_uri=http://fluxtream.dev/o2c.html&realm=777&client_id=4bdc4053-ddb4-45e0-9e70-f5c3fb8db978&scope= was not found on this server

api-docs json is:

"contact": "in...@fluxtream.org",
"license": "Apache 2.0",
}
}

So I have no idea from where it's figuring out this url...


To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.

tony tam

unread,
May 2, 2014, 5:28:12 PM5/2/14
to swagger-sw...@googlegroups.com, tony tam, Anne Wright
OH I just thought of something.  It's looking for the implicit flow, not authorization code flow.  Does your server support that?

Candide Kemmler

unread,
May 2, 2014, 5:31:24 PM5/2/14
to swagger-sw...@googlegroups.com, tony tam, Anne Wright
No it doesn't, but shouldn't that be dependent upon the configuration? I.e. this what I have configured Swagger with:

        List<GrantType> grantTypes = new ArrayList<GrantType>();
        TokenRequestEndpoint tokenRequestEndpoint = new TokenRequestEndpoint(String.format("%sauth/oauth2/authorize", env.get("homeBaseUrl")),
                "client_id",
                "client_secret");
        TokenEndpoint tokenEndpoint = new TokenEndpoint(String.format("%sauth/oauth2/token", env.get("homeBaseUrl")), "access_code");
        AuthorizationCodeGrant authCodeGrant = new AuthorizationCodeGrant(tokenRequestEndpoint, tokenEndpoint);
        grantTypes.add(authCodeGrant);
        AuthorizationType oauth = new OAuthBuilder().grantTypes(grantTypes).build();
        ConfigFactory.config().addAuthorization(oauth);
        ConfigFactory.config().setApiInfo(apiInfo);

I thought that the implicit flow was triggered when using ImplicitGrant instead of AuthorizationCodeGrant...

tony tam

unread,
May 2, 2014, 5:49:46 PM5/2/14
to swagger-sw...@googlegroups.com, tony tam, Anne Wright
The swagger-ui supports only the bearer or implicit flow right now.  So you'd have to configure a Implicit grant configuration:

    List<GrantType> grantTypes = new ArrayList<GrantType>();

    ImplicitGrant implicitGrant = new ImplicitGrant(
      new LoginEndpoint("http://localhost:8002/oauth/dialog"), 
      "access_code");

    grantTypes.add(implicitGrant);

Handling the authorization code flow isn't a bunch of work, and perhaps we can work together on getting it supported.  It does, however, have more reliance on the server which can be tricky.
Message has been deleted

Deepthi Enagalur

unread,
Aug 13, 2014, 2:21:03 PM8/13/14
to swagger-sw...@googlegroups.com, anne.r...@gmail.com
Is authorization code flow implemented?

Ron

unread,
Aug 15, 2014, 2:46:02 AM8/15/14
to swagger-sw...@googlegroups.com, anne.r...@gmail.com
Authorization code flow is supported by the spec, but not supported by the UI.
Are you looking for information on how to expose such documentation?


--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Apkrat 9

unread,
Nov 26, 2015, 5:17:18 AM11/26/15
to Swagger, feh...@gmail.com, anne.r...@gmail.com
i am not getting any window to authenticate my access tokens
@ApiOperation(
nickname = "resources on board",
value = "Access resources using valid access token",
notes = "resources on board post action",
httpMethod = "GET")
@ApiResponses(Array(
new ApiResponse(code = 200, message = "Success", response = classOf[String]),
new ApiResponse(code = 400, message = "Bad Request"),
new ApiResponse(code = 500, message = "DB connection error")))
@ApiImplicitParams(Array(
new ApiImplicitParam(value = "insert data for getting access Token", required = true, dataType = "string", paramType = "header")))
def resources = AuthorizedAction(oAuthDataHandler) { request =>
Ok(Json.toJson(request.authInfo))
}

Ron

unread,
Dec 1, 2015, 2:56:19 PM12/1/15
to Swagger, feh...@gmail.com, anne.r...@gmail.com
That alone is not enough. You need to make sure you have defined the OAuth flows and you need to hook it up into swagger-ui as well for now.
Reply all
Reply to author
Forward
0 new messages