CAS JWT/JWK oddities

426 views
Skip to first unread message

Karl Banke

unread,
Apr 18, 2018, 8:21:43 AM4/18/18
to CAS Community
Hello there,

I am using CAS 5.2 and have spent a long time (which translates to a lot of money) on getting JWT Service Tickets to work.

The CAS documentation states here

https://apereo.github.io/cas/5.2.x/installation/Configure-ServiceTicket-JWT.html that this should be configured using the

jwtAsServiceTicket Property

It also states here

https://apereo.github.io/cas/5.2.x/installation/Configuration-Properties.html#jwt-tickets

that the signing key is a JWK

My findings so far:

JWT service tickets do not work at all in CAS 5.2.0. They work in 5.2.4.

But there are some weired "limitations" that I only figured out running CAS inside my debugger.

(a) The property name is wrong. The property that actually leads to anything happening is jwtAsResponse, as others have pointed out in this community.

But even then....I would like to sign my JWTs with a public RSA key in order to allow Single Page Web Applications to validate the keys.

(b) When trying to read the private key, the code does never look for a JWK, but - in PrivateKeyFactoryBean - tries to parse a PEM file.
(c) Even if one is lucky enough to eventually have a RSA key inside the privateKey by supplying a PEM file, you run in trouble because.
-- taataaa --
the AbstractCipherExecutor calls a hardcoded method called EncodingUtils.signJwsHMACSha512
(d) If you chose not to encrypt the JWT payload, you may rest assured that you get another problem, because someone chose to Base64 encode the payload
twice rather than once.


I have also considered using the OpenID Connect flow instead of the JWT Service tokens, but since this is a much more complicated interface my expectation
is that it's implementation is even more broken and its documentation more inaccurate.

Sorry for the rant, but
I am really about to lose patience with CAS that used to be a very usable, well documented and extensible tool.


William E.

unread,
Apr 19, 2018, 12:13:33 PM4/19/18
to CAS Community
I feel ya...  :-)

My biggest concern at the moment, as others have posted about here as well, is the jwt is a url parameter when passed back to the client app.  I would much rather it be a header or cookie or post param or anything really because my concern is until the jwt expiration time anyone who has access to the apache logs, syslogs, etc. of the cas server or the server hosting the client app, or has access to the network logs, or sniff the traffic in some way, could grab that url parameter and masquerade as that user to the client app.

I'm looking at the cas source code in hopes that I can make this an option(and make a pull request) but being a non-spring java developer my head is currently exploding with all the spring/lombok/etc. "magic" I am having to learn.  Not to mention the large amount of highly modularized code.  It's looks well written and well commented, it's just a lot to take in.  Importing it into eclipse created about a hundred or so source folders I am currently perusing.  Argh.

Pascal Rigaux

unread,
Apr 30, 2018, 6:48:03 AM4/30/18
to cas-...@apereo.org
Le 18/04/2018 à 14:21, Karl Banke a écrit :
> (d) If you chose not to encrypt the JWT payload, you may rest assured that you get another problem, because someone chose to Base64 encode the payload
> twice rather than once.

About this issue, see: https://github.com/apereo/cas/pull/3179

William E.

unread,
May 29, 2018, 6:35:33 PM5/29/18
to CAS Community

AxelR

unread,
Jul 1, 2018, 12:42:40 AM7/1/18
to CAS Community
What about Karl's C ("the AbstractCipherExecutor calls a hardcoded method called EncodingUtils.signJwsHMACSha512")?
I am trying to use RSA and it doesn't still work because of this fact.

I have changed TokenTicketCipherExecutor (hard coded call EncodingUtils.signJwsRSASha512((PrivateKey) getSigningKey(), value)) and AbstractCipherExecutor (now providing a getter for the signingKey) and JWT with RSA works!
I know this could not be the solution (signing with a symmetric key won't work) but just to prove that the current implementation (5.2.5) has a bug.
Can someone please confirm this?


Reply all
Reply to author
Forward
0 new messages