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

Support Basic Authentication for Subscribers #6804

Open
markokocic opened this issue Nov 11, 2019 · 10 comments
Open

Support Basic Authentication for Subscribers #6804

markokocic opened this issue Nov 11, 2019 · 10 comments

Comments

@markokocic
Copy link

Right now the consumers that support only basic authentication are not able to use APIs exposed by Api Manager.

Many consumers are not customizable enough to go through the whole OAuth2 dance, but wast majority of even legacy systems support have ability to add consume services secured using basic authentication, and it's mostly the only authentication schema they support.

This includes various SAP products (S4, ERP, Customer Cloud, Marketing Cloud, ...), as well as many other ERP, CRM and other enterprise systems. Without Basic Authentication support in Api Manager, the only alternatives are:

  • Implmenting own half backed Basic Authentication handler on top of Api Manager
  • Stop using Api Manager and look for alternatives.
@TomasTokaMrazek
Copy link

Newly released APIM 3.0.0 does support Basic Auth. We currently use it in our environment.

@markokocic
Copy link
Author

Yes for backend endpoints. For Api I couldn’t find the option.

@TomasTokaMrazek
Copy link

API Publisher -> Runtime Configurations -> Application Level Security
image

@tmkasun tmkasun added 3.0.0 DEPRECATED Label; Use Affected/3.0.0 instead Type/Question labels Nov 12, 2019
@tmkasun
Copy link
Contributor

tmkasun commented Nov 12, 2019

@Tomas-Mrazek correct, Now we support Basic Authentication for API clients as well. You can enable the Basic option under the application-level security as shown above. This will allow API consumers to invoke this API using their username password combination.

@markokocic
Copy link
Author

Ok, looks like I was looking on the same place. Just tested it and it works.

This brings more questions.

How do subscriptions work with basic auth? Seems like any user can invoke any Api, independent of subscriptions? Is there a way to "assign" users to specific applications so that they can invoke only API to which application is subscribed?

If both Prod and Sandbox share the same Gateway, how is determined which one is invoked when doing basic auth?

These two questions wouldn't need an answer if we were to use application key and application secret instead of username and password in basic auth.

Maybe I am missing something, so it would be good if you could point me to the documentation.

@TomasTokaMrazek
Copy link

TomasTokaMrazek commented Nov 12, 2019

How do subscriptions work with basic auth? Seems like any user can invoke any Api, independent of subscriptions? Is there a way to "assign" users to specific applications so that they can invoke only API to which application is subscribed?

No, it should work the same as with oauth2 token. Only subscribed user can invoke API, doesn't matter if via token or Basic Auth.

You can't assign users to applications, because it works the opposite ways - applications belong to user. If you want more fine-grained control, create roles in /carbon console and assign it to the users. In API publisher, go to API settings, change visibility on devportal to specific role. Then create scopes with specific role for each resource, assign this scope to the resource, enable security. Subscribed users than can ivoke the API, but without you assigning a role to the user, they cannot call any protected resource.

If both Prod and Sandbox share the same Gateway, how is determined which one is invoked when doing basic auth?

Good question. I don't know the answer.

By the way, this wouldn't work with consumer key and secret. Endpoint is specified during /token generation AFAIK.

@markokocic
Copy link
Author

markokocic commented Nov 13, 2019

Hi @Tomas-Mrazek and @tmkasun , this is exactly my issue with Basic authentication now. Let me try to summarize my thoughts on the authentication:

OAuth2 - we subscribe App to an Api. Based on the key and secret, we know the App and the Environment. So, in order to allow App to use Api all we need to do is to subscribe it. Then, any user can call that Api given that he knows key and secret.

Static Api Keys - here we know the Key, and that gives enough information to know which Application is calling the Api, and which environment it uses. The concept of App subscribing to the Api in order to use it still applies. We only need to subscribe App to an Api.

Basic authentication as is now - I will call it "user based basic auth". It completely abandons the concept of App and subscription, and requires using different concept (user-based permissions) and different tools like using Carbon admin instead of Publisher or Store/DevPortal. And it can't distinguish between production and sandbox environment when a single gateway is used for both. It also gives additional level of complexity to set up and administer. Now it's not enough to look at the list of subscribed Apps, one must also go to carbon admin and look at the users and permissions. And if I want to rate limit one specific App for an Api, or have different subscription levels, I can't do that for the user.

What I would see as a "correct" way of supporting Basic Authentication would be the following:

App-level Basic Authentication - We drop the user from the concept (like with static keys) and use the application authentication instead. Application still needs to subscribe to the Api. Consumer Key and Consumer secret are used as basic authentication credentials. That way we keep App / Api Subscription concept, can continue to use the same tools as for everything else (publisher / devPortal, no need for Carbon Admin), and we know which App uses which Api and which environment based on the keys.

How to get there?

There are two options. Either change the current Basic implementation to the one proposed above, or implement a new one called "App Basic authentication".
There's also a third option, to support both user/pass and key/secret in the existing basic auth, but that's the dirtiest one.

@TomasTokaMrazek
Copy link

Basic Auth implementation is not enough. For example you can limit API visibility on devportal based on roles -> which needs to be created and associated with user via Carbon console.

@tmkasun
Copy link
Contributor

tmkasun commented Nov 14, 2019

Hi @Tomas-Mrazek and @markokocic
Thank you for your suggestions, Please find my answers inline.

How do subscriptions work with basic auth? Seems like any user can invoke any Api, independent of subscriptions? Is there a way to "assign" users to specific applications so that they can invoke only API to which application is subscribed?

Basic auth support for client requests does not require subscriptions to be present. If an API creator has enabled Basic Authentication support for a particular API, That API can be invoked without subscribing to that API (By application).
and @markokocic yes, how subscription works is , An Application subscribed to an API.

Furthermore with Baisc auth:
you still get:

  • Resource level or API level throttling
  • Resource scope validation

you won't get:

  • Subscription level throttling
  • Production & Sandbox environment differentiation

If both Prod and Sandbox share the same Gateway, how is determined which one is invoked when doing basic auth?

Yes, we couldn't differentiate the environment by username and password, Hence when using basic auth, you will not have option to select the environment, Production endpoint will be used.

@Tomas-Mrazek

Endpoint is specified during /token generation AFAIK.

No, Endpoints (Prod & Sandbox) are defined by the API creator when creating the API, API consumers can provide callback URL for an application if they want to use re-direction based grant type(s) (i:e implicit)

@markokocic regarding

App-level Basic Authentication

This is possible with current implementation as well. You can use the client credentials grant type to get token pair on behalf of the application owner.

@markokocic
Copy link
Author

markokocic commented Nov 14, 2019

App-level Basic Authentication

This is possible with current implementation as well. You can use the client credentials grant type to get token pair on behalf of the application owner.

@tmkasun
Yes, it's possible to use Basic authentication to generate token using client credentials. You use something like this:

curl -k -X POST https://localhost:8243/token -d "grant_type=client_credentials" -H "Authorization: Basic Base64(consumer-key:consumer-secret)"

However, to use the API, your consumer still needs to be able to:

  • generate the token using the method above
  • set it as a http "Authorization" header with Bearer and Token for the actual API request
  • eventually take care of token expiration and refresh

It's OK if a programmer program your consumer, or you have a vendor that can do it. As described, the issue is with many legacy enterprise clients that are not customizable. For example in SAP if you want to consume external service the only thing you can set is URL, and optionally username and password for basic authentication. There you don't have ability to fetch token or set custom headers.

What I described as App-level Basic Authentication above is actually the ability to skip the step of token generation, and directly use Basic Authentication based on client credential to invoke the API.

Something like:

curl -k -X POST https://localhost:8243/my/nice/Api/doSomething -H "Authorization: Basic Base64(consumer-key:consumer-secret)"

This would allow me to still use the same App to API subscription model in an uniform way, without the need to create, setup and manage users.

As another benefit, since Basic authentication standard provides an ability to include authorization header as part of the URL, we could even support legacy Consumers with something like this:

curl -k -X POST https://consumer-key:consumer-secret@localhost:8243/my/nice/Api/doSomething

EDIT: Now that I think about it, maybe the clearer name would be the Client-Credentials based Basic Authentication for API.

@rmsamitha rmsamitha added Affected/3.0.0 and removed 3.0.0 DEPRECATED Label; Use Affected/3.0.0 instead labels Apr 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants