Documentation: Use standard/existing JWT claims

Created on 18 Oct 2017  路  16Comments  路  Source: Islandora/documentation

Currently we use purely custom claims for JWT whose structure are drupal based: uid, roles, etc...

There are standard/existing claims out there we can utilize instead. First step is to see if any of the undelrying libraries we use in Java and PHP support them.

Most helpful comment

ok cool, I'll work with the Servlet API and see what kind of damage I can do there. Thanks for your assistance @acoburn and @ajs6f

All 16 comments

The PHP library allows setting both standard and custom claims (the code is already doing some of both), so changing the custom claims to standard claims is just a matter of changing one string to another.

On the Java side, I have had good luck using the Java io.jsonwebtoken/jjwt library. It allows for arbitrary claims, but it makes it easy if you're using standard claims. For instance: https://static.javadoc.io/io.jsonwebtoken/jjwt/0.9.0/io/jsonwebtoken/Claims.html

This means that reading the claims is as simple as Claims::getSubject() or Claims::getIssuer(). And for custom claims, it's like this: Claims::get("webid", String.class)

In playing with this I was back inside Syn and I want to try converting it to a ServletFilter. This removes the dependencies on Tomcat. But also removes the availability of the Digester. So then I looked at replacing the syn-settings.xml with a YAML file. Just wondering if this seems like a bad idea from anyone?
Using jackson I was able to pretty easily parse this into our current data structures for one of the existing unit tests.

version: 1
site:
  url: http://test.com
  algorithm: HS256
  encoding: plain
  key: test data

@whikloj No tomcat dependency and yaml instead of xml? Works for me.

@whikloj 馃憤 x 100

Ok, I'll move forward with this tentatively as I'm a novice at it. This will mean we will want to alter Crayfish to be able to handle the same YAML structure.

When I have something in a PR form I'd appreciate all input and suggestions.

There are a number of servlet filters defined in Trellis: https://github.com/trellis-ldp/trellis/tree/master/trellis-http/src/main/java/org/trellisldp/http (look for any class that ends in Filter.java. You may be particularly interested in the AgentAuthorizationFilter which reads from the security context -- your code would just do the inverse: setting the value of your security Principal.

An example where I set the Principal from JWT claims is here: https://git.io/vNBmN (though that code is in the context of a dropwizard.io application)

@acoburn being that this (I think) has to be a ServletFilter as we will use this to secure Fedora. What I have seen is people that read the JWT and if it authenticates basically pass along the chain a "fake" Principal with the parsed name and roles...

I like your AgentAuthorizationFilter but can I use that as a standalone Filter to be used outside of a full JAX-RS application? Like I said, this is really new to me.

@whikloj as I understand it, if you want your code to be independent of Tomcat, you will want to make use of JAX-RS interfaces (JAX-RS being the successor of the Servlet API). That is, while it's possible to just use the servlet-api, I'd recommend using JAX-RS. Also, if this is something that would run alongside Fedora, you will already have Jersey (a JAX-RS impl) available.

@acoburn, I'm not sure that is a good move. Whether or not we think of JAX-RS as in some sense a successor to the Servlet API, the Servlet API is alive and well, and it is what tomcat/Jetty/etc. implement-- not JAX-RS. This is what @whikloj ultimately would implement there.

What brings a JAX-RS impl into the mix is a specific impl of Fedora, and writing to an impl is not what I would prefer to see. Staying agnostic with the Servlet API seems stronger to me.

@acoburn @ajs6f So my reading seems to indicate that either the new JAX-RS methods (like ContainerRequestFilter) or the older ServletFilter are both just implementations of the Filter. If I go with a straight ServletFilter...the work should be transferable if we decide later to use the fancier JAX-RS methods? right?

They are _not_ the same, but the business logic that you write for either should be reusable. The real work is writing the filtering logic. The rest is packaging. If we decide to switch later, it's not a huge deal.

If you expect to wire this filter in via web.xml, you should use the Servlet API (which is entirely independent of Tomcat).

@ajs6f thanks for chiming in here (I was hoping you would). I agree that the servlet-api Filter is the way to go here.

ok cool, I'll work with the Servlet API and see what kind of damage I can do there. Thanks for your assistance @acoburn and @ajs6f

Stands up on creaky legs, toddles off grumbling "Plain old Servlet API was good enough for my grand-dad, it's good enough for me! Damn kids with their fancy resource-mapping-based MVC style and their magic annotations and dynamic bindings!
My hero

Ok back to the actual subject of this ticket.

So here is what I am thinking and let me know if this makes sense. Some of these might be dropped later, but for now.

| Current claim | Description | New claim |
| --- | --- | --- |
| id | Drupal user number | webid |
| name | Drupal user name | sub |
| url | Drupal hostname | iss |
| roles | Drupal roles | roles |

For the id -> webid, we can consider either dropping it or altering it to be a full URI to the users account.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DiegoPino picture DiegoPino  路  5Comments

ruebot picture ruebot  路  4Comments

dannylamb picture dannylamb  路  3Comments

Natkeeran picture Natkeeran  路  3Comments

jonathangreen picture jonathangreen  路  3Comments