git clone https://github.com/openliberty/guide-security-intro.git
cd guide-security-intro
Securing a web application
Prerequisites:
Learn how to secure a web application through authentication and authorization.
What you’ll learn
You’ll learn how to secure a web application by performing authentication and authorization using Jakarta EE Security. Authentication confirms the identity of the user by verifying a user’s credentials while authorization determines whether a user has access to restricted resources.
Jakarta EE Security provides capability to configure the basic authentication, form authentication, or custom form authentication mechanism by using annotations in servlets. It also provides the SecurityContext API for programmatic security checks in application code.
You’ll implement form authentication for a simple web front end. You’ll also learn to specify security constraints for a servlet and use the SecurityContext API to determine the role of a logged-in user.
Getting started
The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:
The start
directory contains the starting project that you will build upon.
The finish
directory contains the finished project that you will build.
Before you begin, make sure you have all the necessary prerequisites.
Try what you’ll build
The finish
directory in the root of this guide contains the finished application. Give it a try before you proceed.
To try out the application, first go to the finish
directory and run the following Maven goal to build the application and deploy it to Open Liberty:
cd finish
mvn liberty:run
After you see the following message, your Liberty instance is ready:
The defaultServer server is ready to run a smarter planet.
The finished application is secured with form authentication.
Navigate your browser to this URL to access the application: http://localhost:9080
The application automatically switches from an HTTP connection to a secure HTTPS connection and forwards you to a login page. If the browser gives you a certificate warning, it’s because the Open Liberty instance created a self-signed SSL certificate by default. You can follow your browser’s provided instructions to accept the certificate and continue.
Sign in to the application with one of the following user credentials from the user registry, which are provided to you:
Username |
Password |
Role |
Group |
alice |
alicepwd |
user |
Employee |
bob |
bobpwd |
admin, user |
Manager, Employee |
carl |
carlpwd |
admin, user |
TeamLead, Employee |
dave |
davepwd |
N/A |
PartTime |
Notice that when you sign in as Bob or Carl, the browser redirects to the admin
page and you can view their names and roles. When you sign in as Alice, you can only view Alice’s name. When you sign in as Dave, you are blocked and see an Error 403: Authorization failed
message because Dave doesn’t have a role that is supported by the application.
After you are finished checking out the application, stop the Liberty instance by pressing CTRL+C
in the command-line session where you ran Liberty. Alternatively, you can run the liberty:stop
goal from the finish
directory in another shell session:
mvn liberty:stop
Adding authentication and authorization
For this application, users are asked to log in with a form when they access the application. Users are authenticated and depending on their roles, they are redirected to the pages that they are authorized to access. If authentication or authorization fails, users are sent to an error page. The application supports two roles, admin
and user
.
Navigate to the start
directory to begin.
When you run Open Liberty in dev mode, dev mode listens for file changes and automatically recompiles and deploys your updates whenever you save a new change. Run the following goal to start Open Liberty in dev mode:
mvn liberty:dev
After you see the following message, your Liberty instance is ready in dev mode:
************************************************************** * Liberty is running in dev mode.
Dev mode holds your command-line session to listen for file changes. Open another command-line session to continue, or open the project in your editor.
Create theHomeServlet
class.src/main/java/io/openliberty/guides/ui/HomeServlet.java
HomeServlet.java
The HomeServlet
servlet is the entry point of the application. To enable form authentication for the HomeServlet
class, define the @FormAuthenticationMechanismDefinition
annotation and set its loginToContinue
attribute with a @LoginToContinue
annotation. This @FormAuthenticationMechanismDefinition
annotation defines welcome.html
as the login page and error.html
as the error page.
The welcome.html
page implements the login form, and the error.html
page implements the error page. Both pages are provided for you under the src/main/webapp
directory. The login form in the welcome.html
page uses the j_security_check
action, which is defined by Jakarta EE and available by default.
Authorization determines whether a user can access a resource. To restrict access to authenticated users with user
and admin
roles, define the @ServletSecurity
annotation with the @HttpConstraint
annotation and set the rolesAllowed
attribute to these two roles.
The transportGuarantee
attribute defines the constraint on the traffic between the client and the application. Set it to CONFIDENTIAL
to enforce that all user data must be encrypted, which is why an HTTP connection from a browser switches to HTTPS.
The SecurityContext interface provides programmatic access to the Jakarta EE Security API. Inject a SecurityContext instance into the HomeServlet
class. The doGet()
method uses the isCallerInRole()
method from the SecurityContext API to check a user’s role and then forwards the response to the appropriate page.
The src/main/webapp/WEB-INF/web.xml
file contains the rest of the security declaration for the application.
web.xml
The security-role
elements define the roles that are supported by the application, which are user
and admin
. The security-constraint
elements specify that JSF resources like the user.jsf
and admin.jsf
pages can be accessed only by users with user
and admin
roles.
Configuring the user registry
User registries store user account information, such as username and password, for use by applications to perform security-related operations. Typically, Open Liberty would be configured to use an external registry like a Lightweight Directory Access Protocol (LDAP) registry. Applications would access information in the registry for authentication and authorization by using APIs like the Jakarta EE Security API.
Open Liberty provides an easy-to-use basic user registry for developers, which you will configure.
Create theuserRegistry
configuration file.src/main/liberty/config/userRegistry.xml
userRegistry.xml
1<server description="Sample Liberty server">
2 <basicRegistry id="basic" realm="WebRealm">
3 <!-- tag::user-bob[] -->
4 <user name="bob"
5 password="{xor}PTA9Lyg7" /> <!-- bobpwd -->
6 <!-- end::user-bob[] -->
7 <!-- tag::user-alice[] -->
8 <user name="alice"
9 password="{xor}PjM2PDovKDs=" /> <!-- alicepwd -->
10 <!-- end::user-alice[] -->
11 <!-- tag::user-carl[] -->
12 <user name="carl"
13 password="{xor}PD4tMy8oOw==" /> <!-- carlpwd -->
14 <!-- end::user-carl[] -->
15 <!-- tag::user-dave[] -->
16 <user name="dave"
17 password="{xor}Oz4pOi8oOw==" /> <!-- davepwd -->
18 <!-- end::user-dave[] -->
19
20 <!-- tag::group-name-Manager[] -->
21 <group name="Manager">
22 <member name="bob" />
23 </group>
24 <!-- end::group-name-Manager[] -->
25
26 <!-- tag::group-name-TeamLead[] -->
27 <group name="TeamLead">
28 <member name="carl" />
29 </group>
30 <!-- end::group-name-TeamLead[]-->
31
32 <!-- tag::group-name-Employee[] -->
33 <group name="Employee">
34 <member name="alice" />
35 <member name="bob" />
36 <member name="carl" />
37 </group>
38 <!-- end::group-name-Employee[] -->
39
40 <!-- tag::group-name-PartTime[] -->
41 <group name="PartTime">
42 <member name="dave" />
43 </group>
44 <!-- end::group-name-PartTime[] -->
45 </basicRegistry>
46</server>
The registry has four users, bob
, alice
, carl
, and dave
. It also has four groups: Manager
, TeamLead
, Employee
, and PartTime
. Each user belongs to one or more groups.
It is not recommended to store passwords in plain text. The passwords in the userRegistry.xml
file are encoded by using the Liberty securityUtility
command with XOR encoding.
server.xml
1<!-- tag::serverxml[] -->
2<server description="Sample Liberty server">
3
4 <featureManager>
5 <feature>appSecurity-5.0</feature>
6 <feature>faces-4.0</feature>
7 <feature>servlet-6.0</feature>
8 </featureManager>
9
10 <variable name="http.port" defaultValue="9080"/>
11 <variable name="https.port" defaultValue="9443"/>
12
13 <httpEndpoint id="defaultHttpEndpoint" host="*"
14 httpPort="${http.port}"
15 httpsPort="${https.port}" />
16
17 <!-- tag::location[] -->
18 <include location="userRegistry.xml"/>
19 <!-- end::location[]-->
20
21 <application location="guide-security-intro.war" type="war"
22 id="guide-security-intro.war"
23 name="guide-security-intro.war" context-root="/">
24 <!-- tag::application-bnd[] -->
25 <application-bnd>
26 <!-- tag::Security[] -->
27 <!-- tag::security-role-admin[] -->
28 <security-role name="admin">
29 <!-- end::security-role-admin[] -->
30 <!-- tag::Group[] -->
31 <!-- tag::group-name-Manager[] -->
32 <group name="Manager" />
33 <!-- end::group-name-Manager[] -->
34 <!-- tag::group-name-TeamLead[] -->
35 <group name="TeamLead" />
36 <!-- end::group-name-TeamLead[] -->
37 <!-- end::Group[] -->
38 </security-role>
39 <!-- tag::security-role-user[] -->
40 <security-role name="user">
41 <!-- end::security-role-user[] -->
42 <!-- tag::group-name-Employee[] -->
43 <group name="Employee" />
44 <!-- end::group-name-Employee[] -->
45 </security-role>
46 <!-- end::Security[] -->
47 </application-bnd>
48 <!-- end::application-bnd[] -->
49 </application>
50</server>
51<!-- end::serverxml[] -->
Use the include
element to add the basic user registry configuration to your Liberty configuration. Open Liberty includes configuration information from the specified XML file in its configuration.
The server.xml
configuration file contains the security configuration of the Liberty under the application-bnd
element. Use the security-role
and group
elements to map the groups in the userRegistry.xml
file to the appropriate user roles supported by the application for proper user authorization. The Manager
and TeamLead
groups are mapped to the admin
role while the Employee
group is mapped to the user
role.
Running the application
You started the Open Liberty in dev mode at the beginning of the guide, so all the changes were automatically picked up.
HomeServlet.java
Point your browser to the http://localhost:9080 URL.
As you can see, the browser gets automatically redirected from an HTTP connection to an HTTPS connection because the transport guarantee is defined in the HomeServlet
class.
You will see a login form because form authentication is implemented and configured. Sign in to the application by using one of the credentials from the following table. The credentials are defined in the configured user registry.
Username |
Password |
Role |
Group |
alice |
alicepwd |
user |
Employee |
bob |
bobpwd |
admin, user |
Manager, Employee |
carl |
carlpwd |
admin, user |
TeamLead, Employee |
dave |
davepwd |
N/A |
PartTime |
Notice that when you sign in as Bob or Carl, the browser redirects to the admin
page and you can view their names and roles. When you sign in as Alice, you can only view Alice’s name. When you sign in as Dave, you are blocked and see an Error 403: Authorization failed
message because Dave doesn’t have a role that is supported by the application.
Testing the application
Write the SecurityIT
class to test the authentication and authorization of the application.
Create theSecurityIT
class.src/test/java/it/io/openliberty/guides/security/SecurityIT.java
SecurityIT.java
The testAuthenticationFail()
method tests an invalid user authentication while the testAuthorizationFail()
method tests unauthorized access to the application.
The testAuthorizationForAdmin()
and testAuthorizationForUser()
methods verify that users with admin
or user
roles are properly authenticated and can access authorized resource.
Running the tests
Because you started Open Liberty in dev mode, you can run the tests by pressing the enter/return
key from the command-line session where you started dev mode.
You see the following output:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running it.io.openliberty.guides.security.SecurityIT
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.78 sec - in it.io.openliberty.guides.security.SecurityIT
Results :
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
When you are done checking out the service, exit dev mode by pressing CTRL+C
in the command-line session where you ran Liberty.
Great work! You’re done!
You learned how to use Jakarta EE Security in Open Liberty to authenticate and authorize users to secure your web application.
Next, you can try the related MicroProfile JWT guide. It demonstrates technologies to secure backend services.
Guide Attribution
Securing a web application by Open Liberty is licensed under CC BY-ND 4.0
Prerequisites:
Nice work! Where to next?
What did you think of this guide?
Thank you for your feedback!
What could make this guide better?
Raise an issue to share feedback
Create a pull request to contribute to this guide
Need help?
Ask a question on Stack Overflow