Islandora / documentation

Contains islandora's documentation and main issue queue.
MIT License
104 stars 71 forks source link

Re-Implement the Drupal Filter using JWT #520

Closed dannylamb closed 7 years ago

dannylamb commented 7 years ago

Add https://www.drupal.org/project/jwt to the install and be sure to enable the optional module to make it a credentials provider. If any configuration is required to get it going we'll need to export that as well.

Then we need to develop a ServletFilter for tomcat that will verify the tokens, which we should provide upon every write request. This seems like a good starting point: http://stackoverflow.com/questions/30335106/can-tomcat-work-with-jwt-token. Though I'm sure there will be some extra tomcat setup and general fun doing a java project setup.

To verify this issue is resolved, once properly configured:

ajs6f commented 7 years ago

Just to be clear here, @dannylamb, you mean a ServletFilter that can work with any web container, right? Not one specific to Tomcat?

dannylamb commented 7 years ago

Yes. Sorry, referring to a generic product with a name brand there. Tomcat's our default, but it should work with any container.

jonathangreen commented 7 years ago

I'll take a crack at this one. May take me a bit of time though.

dannylamb commented 7 years ago

@ajs6f My understanding here is that authn comes from the web server and Fedora doesn't really have to get involved. Are there potentially any configuration bits on fcrepo I might be missing / not aware of?

ajs6f commented 7 years ago

@dannylamb Definitely way the heck outside of any sphere of Fedora's control or interest. AuthZ, different story, but authN, not Fedora's business.

ajs6f commented 7 years ago

Generally, there may or may not be an immediately proximate web server, but anyway, authN comes from upstream.

ruebot commented 7 years ago

@jonathangreen if you need a hand, please don't hesitate to ask.

jonathangreen commented 7 years ago

Don't worry, if anything I will ask too many questions :)

jonathangreen commented 7 years ago

So here is my understanding of this ticket, just going to write it out to get everyones feedback.

We will be using JSON Web Tokens (JWT) for authentication between Islandora, Fedora and the associated micro services. Drupal will be the source of the JWTs. When Drupal emits events events to its queue, it will pass along tokens with them, that can later be used for authorization in various services. Tokens will also be able to be obtained through a REST endpoint. All services will use HTTPS for communication so as not to expose the tokens.

The JSON Web Tokens will be provided in Drupal by the JWT module: https://www.drupal.org/project/jwt

The JWT claim will contain:

header:

{
  "alg": "RS256",
  "typ": "JWT",
  "iss": "site identifier"
}

claim:

{
  "exp": "1234567890",
  "name": "John Doe",
  "roles": ["1", "2", "3"],
  "iss": "site identifier"
}

The JWT header will contain a copy of the site identifier, so that any filter wanting to validate the JWT will know which site it came from in the case where there are multiple Drupal sites communicating with the same services.

We will use the JWS (https://tools.ietf.org/html/rfc7515) algorithm secured with a digital signature to create the tokens. This means that anything wanting to verify the token will only need the public key of the site that issued the token in order to verify its claims.

Fedora will have a servlet filter that will accept the JWT and use this to authenticate the request. The Fedora servlet filter will have a configuration that takes site identifiers and the associated public key which it will use to verify the claims in the token.

Seem reasonable?

ajs6f commented 7 years ago

My comment is just from the Fedora POV: that seems quite reasonable. (Y'all know that the first question is going to be "But does it work with my utterly obscure obsolete institutionally-mandated SSO system?!")

whikloj commented 7 years ago

"Yes as long as your utterly obscure obsolete institutionally-mandated SSO works with JWTs"

jonathangreen commented 7 years ago

(Y'all know that the first question is going to be "But does it work with my utterly obscure obsolete institutionally-mandated SSO system?!")

We can push that off to Drupal. "Yes as long as your utterly obscure obsolete institutionally-mandated SSO works with Drupal."

whikloj commented 7 years ago

So I was doing some reading on this and now I have a question.

I can see how this works when syncing from Fedora to Drupal.

  1. Fedora requests JWT from Drupal
  2. Drupal provides JWT
  3. Fedora sends information to Drupal with JWT
  4. Drupal validates and processes request w/JWT

But how do we plan to use this for Drupal -> Fedora requests? Am I wrong in assuming that Fedora would have to provide a token that Drupal would use with its request and then Fedora would have to validate that token before processing the request.

Is this a place for API-X to come to the rescue or perhaps I skipped a basic point?

jonathangreen commented 7 years ago

So the thing with JWT is they cryptographically sign the JWT. So the flow of information goes something like this:

That lets us pass tokens from drupal -> fedora without having to do database lookups to verify usernames or passwords like we did in D7.

This all assumes that the connections take place over SSL, which in the end will be another part of this request, to ensure that all the inter-service connections happen over SSL.

The pull request to Islandora is just the first in a series of pull requests that will come out of this issue.

I still need to work on:

whikloj commented 7 years ago

Also on this topic https://github.com/cerker/jwt-example

DiegoPino commented 7 years ago

@jonathangreen @whikloj ok! Should we have a quick discussion/planning meeting about this for the drupal ->fedora part?. Mostly because I don't see how things like WebAC fit in that user-less schema.

jonathangreen commented 7 years ago

@DiegoPino the schema isn't userless. The user, and their roles get passed to Fedora in the JWT.

After the JWT is validated then Fedora will have all the information in the JWT to use:

{
  "exp": "1234567890",
  "iss": "1234567890",
  "drupal": {
    "uid": "1",
    "name": "username",
    "roles": ["rolea", "roleb", "rolec"],
    "url": "https://mysite.com"
  }
}

If we want to have a planning discussion about this, maybe we could add it to the agenda for the CLAW call this week. I'd like to have @dannylamb in on the call, since he created this ticket.

DiegoPino commented 7 years ago

@jonathangreen ok! again, cool. I like planning and stuff but it is not required if you all feel you know your way. What I like most is understanding stuff! (so thanks for that clarification). So: all that user data is passed to the queue (JMS) and then (have to check the workflow that dani wrote since I can't remember in which order that went) read by camel, which then uses that info to call Fedora camel component?. Starting to get that, slowly, slowly. Thanks!

whikloj commented 7 years ago

Okay so let me know if I missed something (or everything) here

At the end of the Drupal -> Camel -> Fedora chain.

  1. Fedora receives the request with the JWT
  2. it decodes the JWT
  3. it gets the issuer (which is the Drupal site URL)
  4. it sends the JWT to some special Drupal URL to verify the JWT and return a response code.
  5. then Fedora can either process the request or fail.

I'm guessing that for step 4 we could make use of a new public or private claim like "validationURL", like /jwt/isValid. Where the concatenation of iss and vURL make a REST endpoint that responds if a passed JWT is valid (ie. http://drupal-site.org/jwt/isValid)?

jonathangreen commented 7 years ago

@whikloj there is no call back to Drupal from the Fedora side.

  1. Fedora receives the request with the JWT
  2. it decodes the JWT
  3. it gets the issuer (which is the Drupal site URL)
  4. looks up the sites public key in a configuration file
  5. verify the signature on the JWT
  6. then Fedora can either process the request or fail.
whikloj commented 7 years ago

@jonathangreen thanks, I think my understanding of the public/private key verifying was...missing something.

jonathangreen commented 7 years ago

So final puzzle piece is here: https://github.com/jonathangreen/syn

That repo implements a valve that can be used in tomcat so fedora4 will accept islandora's JWTs.

jonathangreen commented 7 years ago

I think whenever someone is ready to pull the trigger, these pull requests are good to go in now from my perspective.

ruebot commented 7 years ago

Partially resolved with: https://github.com/Islandora-CLAW/islandora/commit/afcd377f9efad659f0dc81323e14c3fd46c8cfd2

ruebot commented 7 years ago

Partially resolved with: https://github.com/Islandora-CLAW/Alpaca/commit/5cd05d8f40255eccb92a27ee58b81ab2a7b4e3ee

ruebot commented 7 years ago

Third and final commit: https://github.com/Islandora-CLAW/claw_vagrant/commit/0d633be36bf3aa7ca18efef3e12f228c86d89f55