JWT and Soteria

334 views
Skip to first unread message

Werner Keil

unread,
Mar 8, 2018, 1:31:22 PM3/8/18
to Eclipse MicroProfile
Hi,

I tried to add Microprofile JWT to my own fork https://github.com/keilw/javaee-soteria-jwt of a very nice PoC for JWT and Soteria.
The PoC works well in the app server of our choice, not all Microprofile JWT implementations do btw. Most of them make assumptions about a very special environment, the Wildfly one only works in Wildfly Swarm, the Hammock one only seems restricted to Hammock or maybe some other Apache projects like TomEE (won't work in Wildfly Full EE either) The only one that does not break the app and prevents deployment seems KumuluzEE, but even that won't work with Soteria and the Java EE Security API as it seems. One issue looks like it only returns the JAX-RS SecurityContext but not one for JSR 375. 

It will be an interesting challenge for JakartaEE/EE4J as one of the only options I could see is if a future version of JAX-RS under EE4J was to simply extend the JSR 375 counterpart. They return almost the same things, getPrincipal() is not called getCallerPrincipal() but otherwise they behave very similar. Except they know nothing of each other, hence if a MP implementation only supports JAX-RS it won't work with Soteria. 
Maybe if Payara implements Microprofile JWT it could do better thanks to the first-hand knowledge by Arjan. 

It could however even require a Microprofile 2.x branch that fully supports Java EE 8 APIs including JSR 375 before that realy works.

Regards,
Werner

Rudy De Busscher

unread,
Mar 9, 2018, 1:13:17 AM3/9/18
to Eclipse MicroProfile
Hi Werner,

The 'issue' (although it isn't issue but related to the poor standardization around authentication and authorization) with MicroProfile JWT Auth is the fact that it needs to be integrated with the code who produces Principal and checks the @RolesAllowed and isUserInRole().

The closest thing what is possible is using JASPIC (which is not available for MicroProfile and some 'full' application servers have slightly deviant behavior)

I also tried to implement it in a generic way (using JASPIC, Java EE 7; see https://github.com/atbashEE/atbash-jwt-sec) but failed because JASPIC is not fine-grained enough. You need to protect only the URL defined at the ApplicationPath and all other URLs should be using the configured one within web.xml. But since the JASPIC handler takes all requests, you no longer have access to the 'default' behavior, so you are stuck.


I find it perfectly normal that the Microprofile specs aren't available in the 'full' versions of the servers, as they are targetted to environments where you just need JAX-RS and CDI. And, isn't it strange that you want to use Rest concepts in an application where you want to use JSF; JSP, MVC etc ...

However, there are some useful specs for the 'full' stack, like config for example. But there is Apache Geronimo Config for example which can be used on any server.

Myself I'm creating an implementation of Rest client which is generic useable (code not available yet). If you are using Apache CXF, you have it already as it is implemented over there already.

my 2 cents :)
Rudy

Werner Keil

unread,
Mar 9, 2018, 2:18:10 PM3/9/18
to Eclipse MicroProfile
Hi Rudy,

Thanks for your input. I also have your talk about securing REST endpoints on the shortlist at JavaLand, because contributing to Java Lobby Day and helping adopt JSRs gave me an extra day ticket and the client is also fine with me staying the extra day.

CU,
Werner


On Friday, March 9, 2018 at 7:13:17 AM UTC+1, Rudy De Busscher wrote:
Hi Werner,

The 'issue' (although it isn't issue but related to the poor standardization around authentication and authorization) with MicroProfile JWT Auth is the fact that it needs to be integrated with the code who produces Principal and checks the @RolesAllowed and isUserInRole().

The closest thing what is possible is using JASPIC (which is not available for MicroProfile and some 'full' application servers have slightly deviant behavior)

I also tried to implement it in a generic way (using JASPIC, Java EE 7; see https://github.com/atbashEE/atbash-jwt-sec) but failed because JASPIC is not fine-grained enough. You need to protect only the URL defined at the ApplicationPath and all other URLs should be using the configured one within web.xml. But since the JASPIC handler takes all requests, you no longer have access to the 'default' behavior, so you are stuck.


I find it perfectly normal that the Microprofile specs aren't available in the 'full' versions of the servers, as they are targetted to environments where you just need JAX-RS and CDI. And, isn't it strange that you want to use Rest concepts in an application where you want to use JSF; JSP, MVC etc ...

However, there are some useful specs for the 'full' stack, like config for example. But there is Apache Geronimo Config for example which can be used on any server.

Myself I'm creating an implementation of Rest client which is generic useable (code not available yet). If you are using Apache CXF, you have it already as it is implemented over there already.

my 2 ents :)

Arjan Tijms

unread,
Mar 9, 2018, 2:50:29 PM3/9/18
to Eclipse MicroProfile
Hi,

>Maybe if Payara implements Microprofile JWT it could do better thanks to the first-hand knowledge by Arjan. 

I implemented MicroProfile JWT a short while ago for Payara. The actual authentication part was really easy to do as EE Security authentication mechanism and identity store and took about an afternoon of work. See https://github.com/payara/Payara/tree/master/appserver/payara-appserver-modules/microprofile/jwt-auth/src/main/java/fish/payara/microprofile/jwtauth

Specifically:



A bit of work was the @RolesAllowed annotation, which MP-JWT demands to work on JAX-RS. This could mostly be done using JAX-RS standard APIs, see:

Dynamic feature that checks for the annotation being present: 


JAX-RS filter that triggers authentication:


The only thing I couldn't find is how to register the dynamic feature using JAX-RS standard APIs, so I used a Jersey API for that.

The bulk of the work of implementing MP-JWT went into its rather elaborate build-in conversion logic, where you inject fields from the token with tons of implicit and stacked conversions. That took a long time to get exactly right.

Clearly the specification of JAX-RS having to support @RolesAllowed, and even more the troublesome @LoginConfig annotation do not belong in the MP-JWT spec, which should just be an JWT authentication mechanism and store and nothing else. But since nor JAX-RS, nor other functionality in MP provided these functions I guess they just quickly stashed it in there. I'd argue for a revision of MP-JWT to remove these again soon.

(anecdotical; JSF made the same grave mistake by quickly stashing the @ManagedBean annotation in its spec, and this has been a MAJOR source of errors and confusion ever since).

Also, if JAX-RS was simply a CDI bean and nothing else (like the MVC spec demands), the @RolesAllowed functionality could have been a CDI interceptor.

Kind regards,
Arjan Tijms

Arjan Tijms

unread,
Mar 9, 2018, 4:57:55 PM3/9/18
to Eclipse MicroProfile
Hi,


On Friday, March 9, 2018 at 7:13:17 AM UTC+1, Rudy De Busscher wrote:
I also tried to implement it in a generic way (using JASPIC, Java EE 7; see https://github.com/atbashEE/atbash-jwt-sec) but failed because JASPIC is not fine-grained enough. You need to protect only the URL defined at the ApplicationPath and all other URLs should be using the configured one within web.xml. But since the JASPIC handler takes all requests, you no longer have access to the 'default' behavior, so you are stuck.

 I understand what you're saying, however this is not a requirement of MP-JWT (yet). MP-JWT 1.0 specifies that if JWT authentication is activated it's at the same level of the one in web.xml (or JASPIC, or EE Security), i.e. you can only have 1 authentication mechanism active in the application.

This is something that was in scope for EE Security, but as you may remember we didn't get to it. Hopefully for EE Security.next ;)

I think JWT Auth absolutely makes sense for full server as well, since the full server has JAX-RS, and why wouldn't you want JWT for that too?

My implementation is nearly 100% Payara independent btw. If you'd fork the code, package it as a separate jar, and only ask the user to register the JAX-RS dynamic feature themselves it should work on Tomcat.

Kind regards,
Arjan Tijms

Rudy De Busscher

unread,
Mar 10, 2018, 5:34:57 AM3/10/18
to microp...@googlegroups.com
Arjan,

you can only have 1 authentication mechanism active in the application.

Within Java EE/Jakarta EE. But strictly speaking, MicroProfile can do something else. And the MP JWT spec isn't too explicit what @LoginConfig does.

Rudy

--
You received this message because you are subscribed to a topic in the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/microprofile/13Qo8eaOUKo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to microprofile+unsubscribe@googlegroups.com.
To post to this group, send email to microp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/microprofile/428abc64-9dae-4c7d-823e-54240faedbc8%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Arjan Tijms

unread,
Mar 10, 2018, 6:07:48 AM3/10/18
to Eclipse MicroProfile
Hi,


On Saturday, March 10, 2018 at 11:34:57 AM UTC+1, Rudy De Busscher wrote:
you can only have 1 authentication mechanism active in the application.

Within Java EE/Jakarta EE. But strictly speaking, MicroProfile can do something else.

Indeed, although that would make the practical implementation of MicroProfile quite hard, as practically speaking most are based on Java EE technology.

The MP JWT spec does say this btw:


An extended form of authorization on a per service basis using a "resource_access" claim has been postponed to a future release. See Future Directions for more information.

Which is not exactly the same, but close.

 
And the MP JWT spec isn't too explicit what @LoginConfig does.

Indeed, but you can hardly blame the spec. It was decided that JWT support was needed for MicroProfile, but then it was discovered that there actually wasn't much foundation in MP to build it on, so a stand-in foundation was seemingly somewhat hastily added.

The spec says as much:

Since the MicroProfile does not specify a deployment format, and currently does not rely on servlet metadata descriptors, we have added an org.eclipse.microprofile.jwt.LoginConfig annotation that provides the same information as the web.xml login-config element. It’s intended usage is to mark a JAX-RS Application as requiring MicroProfile JWT RBAC as shown in the following sample:

So the LoginConfig annotation may or may not hold only for JAX-RS, and it may or may not be used to define other authentication mechanisms to be used as well, despite that it's intended usage is only "to mark a JAX-RS Application as requiring MicroProfile JWT RBAC". 

There's also no place in the LoginConfig annotation to define the parameters needed for JWT.

Strangely though, but mirrored from the web.xml version, the realmName element is there:

 /**
     * The realm name element specifies the realm name to
     use in HTTP Basic authorization.
     * @return
     */
    public String realmName() default "";

As the documentation says, it's ONLY used for HTTP Basic authorization. But despite that, WildFly Swarm uses it to put the JBoss specific security domain in (which is also more or less mandatory on WildFly).

Also despite it mirroring the the web.xml element, the FORM parameters are missing, so it doesn't quite match web.xml at all.

The documentation for authMethod says:

Supported values include
     * "BASIC", "DIGEST", "FORM", "CLIENT-CERT", "MP-JWT", or a vendor-specific
     * authentication scheme.

But if FORM is used, where does one specify the login page and the error page?

Altogether I think @LoginConfig should just be removed from the JWT spec.

Kind regards,
Arjan Tijms






 

Rudy

On 9 March 2018 at 22:57, Arjan Tijms <arjan...@gmail.com> wrote:
Hi,

On Friday, March 9, 2018 at 7:13:17 AM UTC+1, Rudy De Busscher wrote:
I also tried to implement it in a generic way (using JASPIC, Java EE 7; see https://github.com/atbashEE/atbash-jwt-sec) but failed because JASPIC is not fine-grained enough. You need to protect only the URL defined at the ApplicationPath and all other URLs should be using the configured one within web.xml. But since the JASPIC handler takes all requests, you no longer have access to the 'default' behavior, so you are stuck.

 I understand what you're saying, however this is not a requirement of MP-JWT (yet). MP-JWT 1.0 specifies that if JWT authentication is activated it's at the same level of the one in web.xml (or JASPIC, or EE Security), i.e. you can only have 1 authentication mechanism active in the application.

This is something that was in scope for EE Security, but as you may remember we didn't get to it. Hopefully for EE Security.next ;)

I think JWT Auth absolutely makes sense for full server as well, since the full server has JAX-RS, and why wouldn't you want JWT for that too?

My implementation is nearly 100% Payara independent btw. If you'd fork the code, package it as a separate jar, and only ask the user to register the JAX-RS dynamic feature themselves it should work on Tomcat.

Kind regards,
Arjan Tijms

--
You received this message because you are subscribed to a topic in the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/microprofile/13Qo8eaOUKo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to microprofile...@googlegroups.com.

To post to this group, send email to microp...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages