-
-
Notifications
You must be signed in to change notification settings - Fork 452
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
PKCE client authentication in shared public/private server #146
Comments
I don't think I'm going to support this case in Authlib. But you can rewrite According to my experience, one client SHOULD have only one client type. For instance, in https://tools.ietf.org/html/rfc7591 client will have a certain |
Do you have an example of a service where clients are explicitly either public or private? In my experience most OAuth2 providers allow a client to be both public and private so that the client can authenticate in its preferred method across multiple platforms. For example, if you have an application that logs into Google on the web and also on mobile you use PKCE on the mobile app but normal authorization code flow on the web. With how Authlib is designed this is not natively possible. If you refer to https://tools.ietf.org/html/rfc6749#section-2.1 on client types, you can see some important points:
Authlib configuration is currently assuming the client type based on stored configuration rather than based on the authorization request itself.
This is essentially my argument from above, whereby you have multiple clients in different security contexts.
This is essentially the state of Authlib right now, which is what I would like to avoid. Most OAuth2 servers do not require clients to explicitly predefine their client type. |
Yes, you are right. I just found that I want to remove |
That looks close, but I think there's still an issue with that fix. If you set A proper fix for this might be that the grant type should be responsible for knowing what auth methods are supported. For example, for implicit grant and rfc7636 only Edit: It looks like many of the grants do this already with |
@night In # public client MUST verify code challenge
if self.required and request.auth_method == 'none' and not verifier:
raise InvalidRequestError('Missing "code_verifier"') Note this |
hmmm I see.. that should work. will try it out later today to confirm. my only remaining question would be, should this become the default behavior? usually you want to minimize footguns, and I can totally see someone not reading/understanding the implications of adding PKCE without come to think of it, it would be cool if when you extended authorization grant with
|
Also make CodeChallenge required=True by default. ref: #146
@night I've changed the default value to |
I tried upgrading to latest commit to test out this fix, but we now have failing tests that appear to be caused by changes to scope validation in 18858b7
After digging through this commit it looks like it checks arbitrary configuration on the server called |
@night see authlib/example-oauth2-server#52 It is changed to omit the unsupported scopes of the client. You can rollback the checking by rewriting |
@lepture I'm not sure I understand. From your code:
this is stating if the request provided a scope and the server has arbitrary metadata. why does the server need to have this stored? clients may have access to different scopes (i.e. doing the following will effectively achieve what you want, no?
|
@night the metadata is designed for https://tools.ietf.org/html/rfc8414 If you have defined Authorization Server Metadata, there may be a From the spec RFC6479:
In this case, the requested scope is Oh, I just found that you can't rollback to previous behavior now. There is no I'll make a v0.12.1 release to fix it. From my understanding of https://tools.ietf.org/html/rfc6749#section-3.3 I would say, if the requested scope is not in client allowed scopes, authorization server would just omit it. For instance:
But the client only allows
Please correct me if I am wrong. However, I will still make a new release, so that you can rewrite the validate_requested_scope method to rollback the behavior. |
v0.12.1 was released. If you want to rollback to previous behavior, here is the sample code: class YourAuthorizationCodeGrant(grants.AuthorizationCodeGrant):
# implement missing methods
def validate_requested_scope(self):
client = self.request.client
scopes = scope_to_list(self.request.scope)
if set(client.scope.split()).issuperset(set(scopes)):
raise InvalidScopeError(state=self.request.state) |
@@ -31,6 +31,12 @@ class OAuth2Client(db.Model, OAuth2ClientMixin):
db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'))
user = db.relationship('User')
+ def check_endpoint_auth_method(self, method, endpoint):
+ if endpoint == 'token' and method == 'none':
+ return True
+ return super().check_endpoint_auth_method(method, endpoint)
@lepture @night Can you confirm that this is the proper solution to support both PKCE client auth (w/o client_secret) and regular (w/ client_secret) code auth in the same client, without introducing any security issues? Based on my tests in the example app this works fine, but I'd like to know for sure. And if this has no disadvantages, wouldn't it make sense to include a |
The method |
OK, that makes sense. I think then I'll actually override |
Also make CodeChallenge required=True by default. ref: lepture/authlib#146
This issue is similar to my other reported issue #115 but essentially in an authorization server where applications are both public and private it isn't possible to natively authenticate to the token server as a public and private client depending on type of authorization request.
The only way to achieve this currently is to extend the client auth methods with a custom authentication scheme:
This works because
rfc7636
always runsvalidate_code_verifier
afterafter_validate_token_request
, which validates the code verifier provided.The text was updated successfully, but these errors were encountered: