Thanks to visit codestin.com
Credit goes to github.com

Skip to content

suggestion add is_confidential to oauth2 base.Client #597

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

Open
jvanasco opened this issue Sep 14, 2018 · 11 comments
Open

suggestion add is_confidential to oauth2 base.Client #597

jvanasco opened this issue Sep 14, 2018 · 11 comments
Labels
Feature OAuth2-Client This impact the client part of OAuth2.

Comments

@jvanasco
Copy link
Contributor

I discovered this as part of #585, but it's a separate (though related) issue...

The base Client object does not track if a client is confidential (or not), however clients must act differently in certain situations depending on this. It looks like this was largely handled by creating a different base class for each 'concept'. I think adding an is_confidential' property to the base Client` class (and set in the subclasses) would allow for more code re-use and just be generally more descriptive and self-documenting.

@skion
Copy link
Member

skion commented Sep 14, 2018

If we do this, would this void or simplify #593 to a large extend? If so, then it might be the better direction in the first place?

@jvanasco
Copy link
Contributor Author

It won't void #593, but I think it would simplify future maintenance and integration with requests_oauthlib.

It looks like several sections of the two libraries are subclassing functions or altering the behavior based on detecting the class type (e.g. WebApplicationClient vs MobileApplicationClient) where the behavior is actually dependent on whether the client is "confidential" or "public".

More importantly, a client being "confidential" or not is an attribute/descriptor of clients in the oAuth2 spec - but it's not explicitly part of the oauthlib clients.

@JonathanHuot
Copy link
Member

To me, a "confidential" client is a client with a secret. So, if we add client_secret into *Client classes like you suggested, we could make is_confidential a property based on the presence of the client_secret.

If we agree on this, we could change #593 to take this into account and it will simplify the implementations.

Does anyone see disadvantages of doing this ?

@jvanasco
Copy link
Contributor Author

jvanasco commented Sep 14, 2018

To the RFC, confidential is the scope of security https://tools.ietf.org/html/rfc6749#section-2.1

Both "public" and "confidential" clients have a client_secret on the "device". The difference is who controls the device. For example, a backend web application is "confidential", but a frontend web application or mobile application is "public".

OAuth defines two client types, based on their ability to
authenticate securely with the authorization server (i.e., ability to
maintain the confidentiality of their client credentials):

confidential
Clients capable of maintaining the confidentiality of their
credentials (e.g., client implemented on a secure server with
restricted access to the client credentials), or capable of secure
client authentication using other means.

public
Clients incapable of maintaining the confidentiality of their
credentials (e.g., clients executing on the device used by the
resource owner, such as an installed native application or a web
browser-based application), and incapable of secure client
authentication via any other means.

The client type designation is based on the authorization server's
definition of secure authentication and its acceptable exposure
levels of client credentials. The authorization server SHOULD NOT
make assumptions about the client type.

A client may be implemented as a distributed set of components, each
with a different client type and security context (e.g., a
distributed client with both a confidential server-based component
and a public browser-based component). If the authorization server
does not provide support for such clients or does not provide
guidance with regard to their registration, the client SHOULD
register each component as a separate client.

This specification has been designed around the following client
profiles:

web application
A web application is a confidential client running on a web
server. Resource owners access the client via an HTML user
interface rendered in a user-agent on the device used by the
resource owner. The client credentials as well as any access
token issued to the client are stored on the web server and are
not exposed to or accessible by the resource owner.

user-agent-based application
A user-agent-based application is a public client in which the
client code is downloaded from a web server and executes within a
user-agent (e.g., web browser) on the device used by the resource
owner. Protocol data and credentials are easily accessible (and
often visible) to the resource owner. Since such applications
reside within the user-agent, they can make seamless use of the
user-agent capabilities when requesting authorization.

native application
A native application is a public client installed and executed on
the device used by the resource owner. Protocol data and
credentials are accessible to the resource owner. It is assumed
that any client authentication credentials included in the
application can be extracted. On the other hand, dynamically
issued credentials such as access tokens or refresh tokens can
receive an acceptable level of protection. At a minimum, these
credentials are protected from hostile servers with which the
application may interact. On some platforms, these credentials
might be protected from other applications residing on the same
device.

@JonathanHuot
Copy link
Member

I think we have to take a decision to:
A) find a solution to the current #597, and postpone #593 review until #597 is fixed
B) postpone #597 to 3.1 or 4.x, and review carefully #593 for integration in 3.0

What's your opinions ? Prefer to tackle both in one, or one step at a time ?

@jvanasco
Copy link
Contributor Author

I did a deepdive into the code. After consideration, it seems like this request (#597) would simply be a method of documenting the type of client at this time. It certainly can wait until after 585/593, which (IMHO) should be handled sooner than later.

While the various subclasses of Client alter their performance based on this attribute, they are also invoking slightly different arguments and endpoints. I don't think there is any potential simplification of code at this point.

@jvanasco
Copy link
Contributor Author

I think it's still actionable.

looking at the current master, and oauth2 only, the is_confidential attribute -- based on public/confidential distinction in the rfc - would be the following

base.py Client
is_confidential = None

backend_application.py BackendApplicationClient
is_confidential = False

legacy_application LegacyApplicationClient
is_confidential = False

mobile_application.py MobileApplicationClient
is_confidential = False

service_appication.py ServiceApplicationClient
is_confidential = False

web_application.py WebApplicationClient
is_confidential = True

@JonathanHuot
Copy link
Member

BackendApplicationClient is always confidential.
MobileApplicationClient is always public.

About the others, they are sometime confidential, sometime public.
I think we can rely on the existence of the client_secret to define if they are confidential or public.
However, it means that's not a class method but an instance method.

Thoughts?

Legacy aka ROPC:
https://tools.ietf.org/html/rfc6749#section-4.3.2

If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.

Web aka AuthorizationCode:
https://tools.ietf.org/html/rfc6749#section-2.1

public
Clients incapable of maintaining the confidentiality of their
credentials (e.g., clients executing on the device used by the
resource owner, such as an installed native application or a web
browser-based application), and incapable of secure client
authentication via any other means.

Service aka Assertion:
https://tools.ietf.org/html/rfc7521#section-4.1

Authentication of the client is optional, as described in
Section 3.2.1 of OAuth 2.0 [RFC6749], and consequently, the
"client_id" is only needed when a form of client authentication that
relies on the parameter is used.

@jvanasco
Copy link
Contributor Author

jvanasco commented Aug 26, 2019 via email

@skion
Copy link
Member

skion commented Aug 26, 2019

I think we can rely on the existence of the client_secret to define if they are confidential or public.

I agree this is how it should be in practice, but technically it is still possible to have a public client using a client_secret. The best practices state the following about this situation:

Authorization servers that still require a statically included shared secret for native app clients MUST treat the client as a public client[...]

If we do what you suggest, the class would be marked as confidential whilst according to the RFC it "MUST" be treated as public. I feel that someone might shoot themselves in the foot if we provide such a gun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature OAuth2-Client This impact the client part of OAuth2.
Projects
None yet
Development

No branches or pull requests

4 participants
@jvanasco @skion @JonathanHuot and others