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

Include auth_time in SpecDates #825

Open
laurids opened this issue Sep 13, 2023 · 2 comments
Open

Include auth_time in SpecDates #825

laurids opened this issue Sep 13, 2023 · 2 comments

Comments

@laurids
Copy link

laurids commented Sep 13, 2023

Is your feature request related to a problem? Please describe.
"auth_time" is not part of the default fields in Claims. When we need to read it, we cannot use claims.get("auth_time", Date.class) because the parameter is in seconds and java.util.Date requires milliseconds.

Describe the solution you'd like
Ideally all the Authentication Information Claims (auth_time, acr, amr) added as getters in Claims, or just auth_time added in DefaultClaims.isSpecDate, to be able to do e.g. claims.get("auth_time", Date.class).

Describe alternatives you've considered
Instead of reading it as a Date directly, we need to do something like:
var authTimeSeconds = claims.get("auth_time", Long.class);
var authTime = authTimeSeconds == null ? null : new Date(authTimeSeconds * 1000);

Additional context
See https://datatracker.ietf.org/doc/html/rfc9068#section-2.2.1

@lhazlewood
Copy link
Contributor

FWIW, Claims.isSpecDate has been migrated to a new internal (impl module only) field/converter concept, where each RFC-standard field (aka 'Parameter') defines what is accepted for values as well as how to convert them to more idiomatic Java types. For example:

static final Field<Date> EXPIRATION = Fields.rfcDate(Claims.EXPIRATION, "Expiration Time");
static final Field<Date> NOT_BEFORE = Fields.rfcDate(Claims.NOT_BEFORE, "Not Before");
static final Field<Date> ISSUED_AT = Fields.rfcDate(Claims.ISSUED_AT, "Issued At");

(The name Field will be renamed shortly to Parameter before the release to match the RFC taxonomy for this concept, but that's beside the point 😅 ).

This is mostly a reflection that the JJWT team implements support for all standards defined by the JOSE Working Group (which are 9 RFCs at the time of writing).

auth_time is technically not in the scope for those specifications, it's part of the OpenID working group specifications, so we have no immediate plans to support additional (non-JOSE) specifications by default.

The reasons for this are a few:

  1. We just haven't gotten around to it yet 😁 . We want to be 100% feature-finished on the JOSE specifications first.
  2. The IANA list of Claims across specifications is fairly large, and could add an implementation and maintenance burden across many specifications that we may not be able to handle as a small group of volunteers.
  3. This is probably the biggest: There is a large probability of conflict between what people are using as claims in their JWTs today vs what these other specifications require. For example, the IANA list has a name claim that represents an End-User's full name in displayable form including.... I would think there's a high likelihood that the generic concept of name (or address, etc) could conflict with any number of existing application JWTs value formats (is it a String? A JSON Object? etc)

That said, I would like to support all of these where feasible, but I don't know what that looks like just yet - i.e. should the Parameter concept be made public, and they can be specified on a JwtBuilder and/or JwtParserBuilder? It seems like this would be necessary to avoid conflict with existing JWTs that have conflicting fields with different value structures. But that could also open up a substantial part of the internal impl classes to the API module that I'd rather not do.

In any event, this level of non-JOSE-spec parameters will have to wait until probably after 1.0.

So your approach of getting a Long and converting it yourself is definitely the right approach at the moment.

Finally, thank you once again for a well-written / formatted issue - it really helps!

@lhazlewood
Copy link
Contributor

Also, just writing my thoughts for posterity: An ideal place for this JSON-to-Object unmarshalling behavior would likely be done via the the underlying JSON processor (Jackson, GSON, etc) since those libraries are purpose-built for JSON-to-Java-Instance conversion logic (well, except org.json 😞 ).

For example, Jackson and GSON can take any field and unmarshall it into whatever Java object type you prefer before JJWT ever gets the Map<String,?> value, so just calling claims.get("auth_time") would return an already-constructed Date/Instant/whatever instance. For example:

Instant authTime = claims.get("auth_time", Instant.class);

We (JJWT) don't really want to be in the business of JSON-to-Java unmarshalling when other libraries are wholly dedicated to this concept. That is, we don't want to 'reinvent the wheel' and we'd rather 'stand on the shoulders of giants' for this type of functionality if we can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants