-
Notifications
You must be signed in to change notification settings - Fork 5
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
OIDC introspection endpoint #295
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok from my side.
Why the client_id? As far as I can see, it is a non standard field regarding the linked OAuth2.0 specs. If I understand correctly, this serves as a obscure security measure. Specs clearly states that
which is clearly broken here and instead you rely on this one sentence:
IMHO this is insufficient and breaking the spec. |
AFAIK @filipmelik - if you want to expose it to public network, the NGINX introspection needs to be put in front of the SeaCat API and that will give you required access authorization. It also means that the client_id will be handled by that introspection point. |
@@ -80,12 +80,12 @@ async def introspect(self, request): | |||
client_id = params.get("client_id") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As commented in the MR Overview, I would ditch this alltogether in favor of i.e. OAuth2.0 Client Basic Authz.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Including the client_id and client_secret in the POST body is actually a form of OAuth2.0 Client Basic Authentication. Although admittedly I haven't included the client_secret parameter, since we only support public clients, which do not need any secret (they can have one, but it adds little to no security since anyone can extract the secret).
Anyway, we will yet rethink the authentication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarified on call
not sure I understand TBH. I (as an external party) see Seacat as an Authorization provider. I do not know (and also don't wanna know) the inner details of how seacat works, it it somehow uses nginx or whatever as a system component and if it have some private API endpoints and how they work. That's why I do not know what do you mean by I see it just as an OAuth2.0 Authorization provider and expect all the endpoints the OAuth2.0 spec supports. And AFAIK the OAuth2.0 endpoints should be by nature "publicly" available. That's why I do not see the point of having |
representing the meta information surrounding the token, including whether this token is currently active. | ||
|
||
To protect this endpoint with authorization (as required by RFC7662), use NGINX reverse proxy | ||
with auth_request to an NGINX introspection endpoint, for example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this need more documentation. So as a seacat user:
- what endpoints should I call?
- where do I get the credentials?
- are those credentials different per each oauth client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarified on call
@filipmelik - in the nutshell, SeaCat Auth executes authorisation by "introspection" which is delegated to NGINX (that's NGINX introspection). This is a high-level schema:
How this apply to OIDC introspection endpoint? In this case, the endpoint is exposed on the SeaCat Auth private API (hence Robin's remarks above); then the exposure to "frontends" happens thru "NGINX introspection" and you get the authorization. Ok? |
@@ -120,7 +120,8 @@ async def introspect(self, request): | |||
if "preferred_username" in user_info: | |||
response_data["username"] = user_info["preferred_username"] | |||
|
|||
# TODO: Verify that the token is client_id is included in the aud claim | |||
# TODO: Verify that the requesting client is part of the token's intended audience | |||
# (i.e. that their client_id is included in the aud claim). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will break my usecase in mobile apps. Can we have a call about thiz plz?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't intend to implement this check within this merge request (or anytime soon, unless necessary). it would also require implementing a way for the client to influence the content of the audience
claim somehow, possibly by scope
.
i added the todo as a reminder that the authorization has some limitations and can be improved. the authorization server should not disclose id tokens to just any client. it is mostly fine in environments where there are few clients manually registered by an admin, but not in large environments with open client registration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarified on call
# Conflicts: # CHANGELOG.md # seacatauth/openidconnect/handler/introspect.py # seacatauth/openidconnect/service.py
closes #283
Changes
OAuth 2.0 Token Introspection
POST /openidconnect/token/introspect
.token
with the token value andclient_id
.client_id
query parameter requirement).Example
Request
Response