DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

SBOMs are essential to circumventing software supply chain attacks, and they provide visibility into various software components.

Related

  • What D'Hack Is DPoP?
  • OWASP TOP 10 API Security Part 2 (Broken Object Level Authorization)
  • Secure Your API With JWT: Kong OpenID Connect
  • Maven Dependency Scope Applied

Trending

  • The Evolution of Software Integration: How MCP Is Reshaping AI Development Beyond Traditional APIs
  • Understanding k-NN Search in Elasticsearch
  • Advanced gRPC in Microservices: Hard-Won Insights and Best Practices
  • 12 Principles for Better Software Engineering
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. Using Jakarta Security on Tomcat and the Payara Platform

Using Jakarta Security on Tomcat and the Payara Platform

Learn how to get started with Jakarta Security on Tomcat and Payara.

By 
Arjan Tijms user avatar
Arjan Tijms
·
Jul. 23, 19 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
6.0K Views

Join the DZone community and get the full member experience.

Join For Free

Java EE Security API is one of the new APIs in Java EE eight. With Java EE currently being transferred and rebranded to Jakarta EE, this API will soon be rebranded to Jakarta Security, which is the term we'll use in this article. Jakarta Security is part of the Jakarta APIs, included and active in the Payara Platform by default with no configuration required in order to use it. With some effort, Jakarta Security can be used with Tomcat, as well.  

The API focuses on full standardization (not depending on proprietary server config) and recognizing the use case to configure security from within an application archive. The latter is specifically useful for cloud deployments, where lightweight and self-sufficient war archives can be deployed to generic Jakarta EE compatible containers.   

Jakarta Security is included in the Payara Platform by default and is also active by default. As a result, there is nothing that must be included in a war archive to use Jakarta Security in the Payara Platform and nothing to configure in order for code to use it. Payara uses Soteria, which is the reference implementation under Java EE, but just one of the possible implementations under Jakarta, which did away with the RI concept. Another implementation is available from our friends at Open Liberty, and implementation from TomEE, aptly called TomEE Security is currently underway. 

Soteria was designed with the usage of standard APIs in mind and the ability to run on different servers. Any functionality Soteria requires that isn't available in standard APIs is delegated to an SPI with a default implementation covering a series of well-known servers. This SPI is internal in Soteria 1.0.x, but it will be made public in Soteria 1.1. 

Adding Soteria to Tomcat 

Because Jakarta Security is very much based on Jakarta EE, a valid question to ask is: does it also run on Tomcat? The answer is yes, but with some caveats. 

Jakarta Security depends on Servlet (with the Servlet Container Profile JASPIC extensions), Expression Language and CDI. Soteria additionally depends on JACC, but this is abstracted via its SPI: 

Jakarta Security and SoteriaJakarta Security and Soteria

Tomcat obviously already implements Servlet (with the Servlet Container Profile JASPIC extensions), but it also implements Expression Language. To start getting it to run we first need to add CDI to Tomcat. This basically entails adding a CDI implementation, where Weld is quite easy to use by adding the following to pom.xml in a Maven project: 

Adding dependency to pom.xml

Adding dependency to pom.xml


Subsequently, we also need to register the CDI bean manager in JNDI by adding a META-INF/context.xml file with the following contents:

Adding CDI bean manager

Adding CDI bean manager


Next, we'll add the Soteria implementation:

Adding Soteria implementation

Adding Soteria implementation


We don't necessarily have to include the respective API dependencies (CDI and Jakarta Security), as they are referenced by the implementations, and therefore, automatically fetched by Maven.

 The above should be enough to get things running. (We'll come to the JACC dependency later.) We should look out for the path of the bean manager. Occasionally, the bean manager will get stored under "java:comp/env/BeanManager" instead of its normal path: "java:comp/BeanManager". This is a rather well-known trap, and many projects have adjusted for this, but Soteria hasn't yet. Soteria 1.1 will certainly include a fix for this.

 In the meantime, what we can do is using a handy trick in Servlet, where we can override classes coming from embedded jars (jars in WEB-INF/lib). To do this, we copy the CdiUtils.java file from the Soteria source to a package with the same name in our project. Then, in that file, we change the getBeanManager() method to:

getBeanManager() method

getBeanManager() method


With this all in place we can now code up a simple protected Servlet, using the provided BASIC authentication mechanism:

Example protected Servlet

Example protected Servlet


What we are seeing here is a fairly standard Servlet, with the only extra bit the Jakarta Security annotation for defining the BasicAuthenticationMechanism. Note that while the annotation is put on the Servlet class in this example, it's a global annotation that sets the authentication mechanism for the entire application. Just setting the authentication mechanism from an application may not seem terribly exciting at first sight (one can do this using web.xml as well), but the main difference here is that the authentication mechanism is a CDI bean with a well-defined interface, which opens up lots of options regarding intercepting, decorating and replacing the bean.

Something which can't really be done with plain Servlets and only in a fairly obscure way with the Servlet Container Profile JASPIC extensions on Tomcat is defining the database within the application which is used to validate the credentials and return groups (which map one-to-one to roles by default). With Jakarta Security this is trivial:

MyIdentityScore

MyIdentityScore


Running this on Tomcat, we see the various bits and pieces being initialized and picked up in the server log:

Server log

Server log


Deploying and running this on Tomcat will present us with a well-known browser authentication dialog. If everything went right, we get the following output:

Desired output

Desired output


A fully working example is available in the Vendor EE Samples project.

Adding a JWT Authentication Mechanism

An important aspect of Jakarta Security vs. native Servlet security authentication mechanisms is that the same APIs that are used by the build-in mechanisms are available to build third-party mechanisms as well. For instance, the MicroProfile JWT authentication mechanism can be based on Jakarta Security. In fact, two implementations (Payara MP JWT and SmallRye MP JWT) do. This makes it possible to add those to Tomcat.

 For this tutorial, we'll be looking at Payara MP JWT.  Payara MP JWT, however, is currently not published on Maven central although it can be built from source by cloning and building it using mvn clean install. MP JWT  does have its own additional dependencies, which in terms of APIs are JSON-P and  MP Config. For Tomcat, we have to add implementations for those as well, and we'll do that by adding SmallRye Config and the GlassFish JSON-P implementation. This will make the dependencies we list in our pom.xml quite a bit longer; the implementations actually depend on the APIs, so we don't really need to list them (since Maven will fetch transitive dependencies). Our pom dependency section will then look as follows:

Pom dependency

Pom dependency


With this in place, we can start using MP JWT on Tomcat. As an example application, we will modify an existing MicroProfile sample to make it Tomcat compatible. Without repeating all the existing MP JWT tutorials here, in short using MP JWT means setting the authentication mechanism by placing the @LoginConfig annotation somewhere, and then configuring a public key inside the application that will be used to verify incoming JWT tokens. For the request we sign a JWT token with the corresponding private key and include it in an "authorization" header, for instance using wget:

 wget --header="Authorization: BearereyJraWQiOiJcL3ByaXZhdGVLZXkucGVtIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyNDQwMDMyMCIsImF1ZCI6InM2QmhkUmtxdDMiLCJ1cG4iOiJ0ZXN0IiwiYXV0aF90aW1lIjoxNTYxNDYwOTEwLCJpc3MiOiJvcmcuZWNsaXBzZS5taWNyb3Byb2ZpbGUxMiIsImdyb3VwcyI6WyJhcmNoaXRlY3QiLCJtYXN0ZXIiLCJsZWFkZXIiLCJkZXYiXSwiZXhwIjoxNTcxNDYwOTEwLCJpYXQiOjE1NjE0NjA5MTAsImp0aSI6ImEtMTIzIn0.RLxhWgjyMN39W-3Ls-ppqAJvOeeaUmb4Y8NXKbhjufdAjgkA6x8OhAURQK22z1rBnMM5HMuRWF9uIEbgA7I4A5kdLfiDidEFZsIYFEJEzKBjDHN8Ind5kWY63CppAnTYhJYZ7oN2yfJ7wjfRQLllTBUY59YiZM-yuMEkOhgC9Tk6EpG1Xf390EmhoS7w8DokN89Q5ANrZtcFpIrOQChq-RW60QeKfk13xgfgD1hOqwy3C6K5gWSfP1ceHcoFrtRRqE5vKZmnpxaB82vQZFKJMg7E-iRm9eqtqN4G0ZfMutv0wP2v6SgSkuez_5tj17DHKVYF3dOZXlWfzST_VQw7JQ" http://localhost:8080/jwt/servlet

 If everything went as planned, we will then get the following response:

 This is a protected servlet 

web username: test

web user has role "architect": true

web user has role "bar": false

web user has role "kaz": false

 As we can see, this indeed works on Tomcat, attesting to the already quite modular nature of Jakarta EE and MicroProfile implementation components.

A fully working example is again available in the Vendor EE Samples project. 

The JACC Dependency

Coming back to the missing JACC dependency, which we mentioned at the start of this article: it's used by Soteria to implement the Jakarta Security SecurityContext. Since JACC is mostly about exposing something that a Servlet container does in a standard way (essentially an index of security constraints), you can't really have a standalone implementation of it. The closest would be to manually parse web.xml and manually scan for the associated security annotations, build our own index, and implement the same resolving algorithm as Servlet containers are implementing. OmniFaces takes this approach for its WebXml class, but it's not ideal. The best solution would be for Tomcat to implement the Servlet extensions for JACC, for which some mild interest was shown before. Finally, the upcoming public Soteria SPI could be taken advantage of to use Tomcat's native APIs directly to access its internal security constraints.

With all of this not available for Tomcat there's no alternative at the moment, so we can't use the SecurityContext. Everything else works though. 

Using Jakarta Security on the Payara Platform 

To use Jakarta Security on the Payara Platform, nothing special is needed. It’s just there and ready to go-  just like the Servlet API is just “there”, for example. 

This means any book, tutorial, or example on Jakarta Security can be followed, and nothing Payara-specific has to be done by the user. The following are small examples of using Jakarta Security: 

  • Example apps in Soteria — https://github.com/eclipse-ee4j/soteria/tree/master/test (work on other Jakarta Security implementations too). 
  • Java EE 8 Samples — https://github.com/javaee-samples/javaee8-samples/tree/master/security.
security Apache Tomcat Implementation JWT (JSON Web Token) Java EE application Dependency MPS (format) authentication

Published at DZone with permission of Arjan Tijms. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • What D'Hack Is DPoP?
  • OWASP TOP 10 API Security Part 2 (Broken Object Level Authorization)
  • Secure Your API With JWT: Kong OpenID Connect
  • Maven Dependency Scope Applied

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: