(why) is vertx-auth-oauth2 hardwired to JWT tokens?

117 views
Skip to first unread message

Nikolaus Kühn

unread,
Apr 18, 2018, 8:22:01 AM4/18/18
to vert.x
Hi everyone,

I'm trying to build a small custom REST service that is a relying party in OAuth, i.e. it's providing resources to users but the decision whether a given Bearer token is valid and has what scope is attached is not taken by the service itself. 

So I'm using OAuth2 RFC7662 token introspection to check the token at the auth server.  The system I'm extending is implementing standard OAuth2 but not with JWT tokens but plain OAuth2 as specified. I.e. the access token is an opaque string.  (related spec: "usually opaque" .... "may self-contain".. - nothing says that the token 'must' self-contain information in JWT.

Unfortunately (and although there explicitly is a separate  vertx-auth-jwt  module)  the vertx-auth-oauth2  module is implictly assuming JWT all over the place.   E.g. even though the OAuth2Auth Provider has and "introspect"  method that takes a plain String, internally it's building an AccessToken object and that (although the name does not say it) is hardwired from top to bottom to be a JWT token.   

I ended up copying code out of the AccessToken Implementation and removing all the JWT specific

Is this by design and intended?   Any plans or ideas to  e.g. flag a Provider or an AccessToken as "opaque"?  Removing the JWT hardwiring would be super breakign so I guess the better way would be to allow losening the restrictions explicitly. 

Nikolaus


Paulo Lopes

unread,
Apr 19, 2018, 10:02:28 AM4/19/18
to vert.x
Hi,

The reason is that the same code can be used with OpenID Connect servers which are an extension on top of OAuth2 that uses JWTs as the token format.

Nikolaus Kühn

unread,
Apr 19, 2018, 10:32:49 AM4/19/18
to vert.x

Hi,

thanks, so the original use case was not "OAuth2" alone but actually OIDC. 

How would you imagine plain OAuth support to be included?   Inside the OAuth2 provider (e.g. with additional method signatures that offer handling the token as an opaque string) or would "plain" OAuth2 support have to be a completely separate provider?
I'm happy to help out but cannot promise to stay really involved mid term.

Nikolaus

Nikolaus Kühn

unread,
Apr 19, 2018, 4:44:24 PM4/19/18
to vert.x

P.S. to self:   I played a bit with the current implementation and code-wise it's much simpler - the infrastructure including the matching config and provider flag (isJWT / hasJWT) is already there.  So I sat down and tried to implement it:  https://github.com/vert-x3/vertx-auth/compare/master...nkuehn:issues/xxx-opaque-token-mode 

Problem: The existing flag is implemented with a default of "false" (= not a JWT), but it's not actually respected anywhere in the implementation, so starting to make use of it is formally just implementing the defined interface but practically a breaking change that disables JWT validation in existing implementations. 

Here's the definition of the (until now unused) flag, it's in fact a bit unclear to me since it mixes generic JWT and OpenID connect specifics: https://github.com/vert-x3/vertx-auth/blob/master/vertx-auth-oauth2/src/main/java/io/vertx/ext/auth/oauth2/OAuth2Auth.java#L133

Maybe a useful way to proceed could be to deprecate the until now unused flag and introduce new ones that default to assuming JWT is in use?

No hurry, all just experiments
Nikolaus

Paulo Lopes

unread,
Apr 20, 2018, 3:34:11 AM4/20/18
to vert.x
Currently that flag is used on other components such as vertx-web in order to signal on the web side if it should attempt to use the token for permission checks. I think we probably should do a proper review of the code, as, as I wrote, it has been mutating since its initial inception. It started as a simple Oauth2 and now is becomming a OIDC handler.

I don't see the need to deprecate and create 2 providers as OIDC is an extension of Oauth2 (in a simplified way), so I think probably all we need is to isolate the OIDC code into a separate package (in the impl side as this is a implementation detail) and at configuration time, decide to assume the provider is OIDC compliant or not.

I imagine that knowing at config time if a provider is OIDC compatible or not can allow us to break the `AccessToken` interface in 2:

`AccessToken` as the base for Oauth2
and `OIDCAccessToken` that extends `AccessToken` and adds the OIDC functionality e.g.: id token, userinfo, etc.. etc...

This would also break the internal implementation into 2 making it probably easier to read/maintain?

What do you think?

Nikolaus Kühn

unread,
Apr 20, 2018, 3:52:03 AM4/20/18
to vert.x
Thanks! 

right , I just saw that the "isJWT" / "hasJWT" flag is even used inside the oauth package.  It's actively changed by the Token implementation once it detects that it can handle JWK, i.e. signing and encrypting tokens. So in the implementation it's rather a read-only signal from the library to the application code than a configuration that is changing something in the behavior of the library.

Give me some time to read into it over the weekend.  I'm a bit biasing towards an "treat as opaque token" flag instead of a full refactoring into a  "plain Oauth2" -> JWT -> OIDC (or other)  hierarchy since the edges are blurry anyways in the real-world implementations and a feature flagging approach can be adjusted more flexibly by users.   But that could also be just lazyiness.

Nikolaus
Reply all
Reply to author
Forward
0 new messages