Using 3scale with shared OAuth authorisation server

1.5k views Asked by At

I have a website, mywebsite.com, in which users can log in. Login is handled by redirecting unauthenticated sessions to an SSO provider on ssologin.com, which validates credentials and then redirects back to mywebsite.com with an access token so it can create a local session.

The website is a single page web app that uses JavaScript to call an API exposed through the API gateway 3scale.

What I would like to understand is how I can get 3scale to honour the OAuth access token issued to the website. I'm guessing it should be simple enough given 3scale seems to delegate this to an authorisation URL but I'm unsure about the mechanics behind this and whether it's doing what I'm expecting.

Can anyone explain whether - and how - I can do this? I've read the documentation but I'm having trouble making sense of it because it glosses over what happens AFTER an OAuth access token has been granted, and it doesn't touch on the scenario where the token may be created out-of-band (i.e. out of sight of 3scale).

I think the flow I would want to use in this scenario is the client side web app / implicit grant flow, but please correct me if I'm wrong.

I've tried to decipher the help files but I still have a bunch of questions:

  • I assume I configure the 3scale OAuth login URL as exactly the same URL that mywebsite.com redirects to? Or do I need a different page to handle different logic, and the fact that the API calls are generally not interactive / user-facing?
  • Is the access token returned after the user logs into the website via the ssologin.com OAuth login page usable for subsequent API calls or does 3scale need a token of its own and therefore requires its own login redirect? (Is there state being stored anywhere in the gateway?)
  • How does the access token get passed to the API calls: as a parameter, as an HTTP header, or through some other mechanism?

Actually what I'd LIKE to do is actually use OpenID Connect and get an ID token back as well, but 3scale doesn't natively support this. Is there anything I can do with 3scale to fake this and still return an ID token, effectively making it behave like OpenID Connect?

1

There are 1 answers

2
Pili On BEST ANSWER

TL;DR: Use the 3scale API call to store access_tokens so they will be honoured by 3scale: https://github.com/3scale/nginx-oauth-templates/tree/master/oauth2

curl -X POST "http://su1.3scale.net/services/<SERVICE_ID>/oauth_access_tokens.xml?provider_key=<PROVIDER_KEY>&app_id=<CLIENT_ID>&token=<TOKEN>&ttl=<TTL>"

3scale provides a number of API calls to manage access tokens, this includes storing as well as deleting access tokens. You can find a list of these API calls to manage access tokens in the README here: https://github.com/3scale/nginx-oauth-templates/tree/master/oauth2

As such, you should be able to associate an access token issued outside of 3scale to an application (potentially your single page web app) and use that access token for authorization purposes. In fact 3scale doesn't generate the access tokens, the API Gateway does.

This is all for the purposes of checking that an application in 3scale using a given access token is authorized to call a given API endpoint, i.e authorization only as opposed to authentication and/or identity verification. The user authentication should all have been done outside of 3scale when the user logs in.

3scale provides a number of configuration templates for the API Gateway depending on the flow that you want to implement and whether you want the token to be generated by the API Gateway (token-generation folders) or by an external OAuth provider (no-token-generation folders.) You can find these templates here with some explanation about how they work inside each of the different flow folders: https://github.com/3scale/nginx-oauth-templates/tree/master/oauth2. Since you have your own OAuth provider for generating access tokens, you will need to use these templates instead of the files generated inside the Integration page in 3scale.

To answer your specific questions:

  • The OAuth login url should really be a page (protected behind the ssologin page) that allows your users to authorize/deny access to an application accessing their resources via an API. It seems like your SSO provider does not require this so it seems to be following the resource owner password flow.

  • In this flow (resource owner password) the access token is returned when calling the /oauth/token endpoint on the API Gateway. The Gateway will then call the external OAuth Provider's access token endpoint (with the relevant parameters) and once it receives an access token back, it will store it in 3scale and return it to the calling application. With other flows, it is sent to the redirect url by the API Gateway instead. However, if your SSO provider already returns an access token to your application's redirect url, you can do 2 things:

    1. Call the 3scale endpoint to store the access token returned, directly from your application
    2. Make the redirect_url for the SSO provider be the API Gateway instead of your application so that it stores the access token in 3scale and sends the access_token back to your application also. This will require customizing the API Gateway configuration templates.
  • It is entirely up to you where the access token is sent. However, you would have to configure this location in the Nginx configuration templates so that the access token is extracted correctly. e.g https://github.com/3scale/nginx-oauth-templates/blob/master/oauth2/resource-owner-password-flow/no-token-generation/nginx.lua#L198-L207 and https://github.com/3scale/nginx-oauth-templates/blob/master/oauth2/resource-owner-password-flow/no-token-generation/nginx.lua#L312

Ultimately the Gateway can sit between your application and the access token issuer to capture and store these in 3scale, mediating the whole exchange. The only limit in 3scale is the access token format which has to be an alphanumeric string up to 256 chars long.