Skip to content

Commit

Permalink
Multipane (#77)
Browse files Browse the repository at this point in the history
* Converting to multipane

* Updated README

* Updated README and HomeServlet.java

* Updated README

* Updated README

* Updated README and server.xml

* Updated README

* Updated server.xml format

* Update failsafe/surefire plugin

* Parent POM update

* Updated travis.yml and README

* Updated start/pom.xml

* Updated README

* Updated README

* Updated README and removed tag from security test

* Updated xml elements

* 2nd round - need to see if first stop-server needs to be removed

* Adding the hashtags around code_comand

* Removed finish.adoc include from README.adoc

* Adjusting order of dependencies

* Updating dependency versions

* Updated README with [hotspot] changes

* Updated README with link in new tab changes

* Updated README with link in new tab changes

* Change the guide attribution to point to master

* Updating copyright year, minor README update
  • Loading branch information
andrewdes authored and gkwan-ibm committed Feb 27, 2019
1 parent 15f18dc commit 2de8132
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 159 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ before_script:
- unset _JAVA_OPTIONS
- cd finish
script:
- mvn clean install
- mvn -q clean install
- build=$(grep "Open Liberty" target/liberty/wlp/usr/servers/defaultServer/logs/console.log
| cut -d' ' -f5 | cut -d')' -f1 ); release=$( echo "$build" | cut -d'/' -f1); number=$(
echo "$build" | cut -d'/' -f2); ol_jv=$(grep -i "on java" target/liberty/wlp/usr/servers/defaultServer/logs/console.log);
Expand Down
94 changes: 58 additions & 36 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
// Copyright (c) 2017 IBM Corporation and others.
// Copyright (c) 2017, 2019 IBM Corporation and others.
// Licensed under Creative Commons Attribution-NoDerivatives
// 4.0 International (CC BY-ND 4.0)
// https://creativecommons.org/licenses/by-nd/4.0/
//
// Contributors:
// IBM Corporation
:page-layout: guide
:guide-author: Open Liberty
:page-layout: guide-multipane
:projectid: security-intro
:page-duration: 15 minutes
:page-releasedate: 2018-10-19
:page-description: Learn how to secure a web application through authentication and authorization.
:page-tags: ['REST', 'Security', 'CDI', 'Java EE']
:page-tags: [Java EE']
:page-related-guides: ['microprofile-jwt', 'cdi-intro']
:page-guide-category: none
:page-permalink: /guides/{projectid}
:common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/master
:source-highlighter: prettify
:page-seo-title: Securing a web application
:page-seo-description: Learn how to secure a web application through authentication and authorization using Java EE 8 Security API.
:guide-author: Open Liberty
= Securing a web application

[.hidden]
Expand All @@ -40,19 +42,20 @@ You’ll implement form authentication for a simple web frontend. You'll also le
// =================================================================================================
// Getting Started
// =================================================================================================

[role="command"]
include::{common-includes}/gitclone.adoc[]

=== Try what you'll build

The `finish` directory in the root of this guide contains the finished application secured with form authentication. Feel free to give it a try before you proceed.

To try out the application, first navigate to the `finish` directory and then run the following Maven goals to build the application and run it inside Open Liberty:
[role='command']
```
mvn install liberty:start-server
```

Navigate your browser to this URL to access the application: `http://localhost:9080`
Navigate your browser to this URL to access the application: http://localhost:9080[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 Liberty server created a self-signed SSL certificate by default. You may follow your browser's provided instructions to accept the certificate and continue.

Expand Down Expand Up @@ -87,6 +90,7 @@ When you sign in as Alice, you can only view Alice's name.
When you sign in as Dave, you'll be blocked and will see a `Error 403: Authorization failed` message because Dave doesn't have a role supported by the application.

Once you're done checking out the application, log out and stop the Open Liberty server:
[role='command']
```
mvn liberty:stop-server
```
Expand All @@ -100,32 +104,37 @@ mvn liberty:stop-server
For this application, users will be asked to login with a form when they access the application. Users are authenticated and depending on their roles, they will be redirected to the pages that they are authorized to access. If authentication or authorization failed, users will be sent to an error page. The application supports two roles, `admin` and `user`.

Navigate to the `start` directory to begin.
[role="code_command hotspot", subs="quotes"]
----
#Create the `HomeServlet` class.#
`src/main/java/io/openliberty/guides/ui/HomeServlet.java`
----

Create the `HomeServlet` class in the `src/main/java/io/openliberty/guides/ui/HomeServlet.java` file:

[source, java, indent=0]
HomeServlet.java
[source, java, linenums, role="code_column"]
----
include::finish/src/main/java/io/openliberty/guides/ui/HomeServlet.java[tags=homeservlet;!copyright]
----

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 defining `welcome.html` as the login page and `error.html` as the error page.
The [hotspot=22-50 file=0]`HomeServlet` servlet is the entry point of the application. To enable form authentication for the [hotspot=22-50 file=0]`HomeServlet` class, define the [hotspot=17-19 file=0]`@FormAuthenticationMechanismDefinition` annotation and set its [hotspot=18-19 file=0]`loginToContinue` attribute with a [hotspot=18-19 file=0]`@LoginToContinue` annotation defining [hotspot=19 file=0]`welcome.html` as the login page and [hotspot=18 file=0]`error.html` as the error page.

The `welcome.html` and `error.html` pages that implement the login form and error page respectively 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 Java EE and available by default.
The [hotspot=19 file=0]`welcome.html` and [hotspot=18 file=0]`error.html` pages that implement the login form and error page respectively are provided for you under the `src/main/webapp` directory. The login form in the [hotspot=19 file=0]`welcome.html` page uses the `j_security_check` action, which is defined by Java 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 only, define the `@ServletSecurity` annotation with the `@HttpConstraint` annotation and set the `rolesAllowed` attribute to these two roles.
Authorization determines whether a user can access a resource. To restrict access to authenticated users with `user` and `admin` roles only, define the [hotspot=20-21 file=0]`@ServletSecurity` annotation with the [hotspot=20 file=0]`@HttpConstraint` annotation and set the [hotspot=20 file=0]`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 will be switched to an HTTPS one.
The [hotspot=21 file=0]`transportGuarantee` attribute defines the constraint on the traffic between the client and the application. Set it to [hotspot=21 file=0]`CONFIDENTIAL` to enforce that all user data must be encrypted, which is why an HTTP connection from a browser will be switched to an HTTPS one.

The SecurityContext interface provides programmatic access to Java EE Security API. Inject a SecurityContext instance into the `HomeServlet` class. The `doGet()` method uses the `isCallerInRole()` method from SecurityContext API to check a user's role and then forwards the response to the appropriate page.
The SecurityContext interface provides programmatic access to Java EE Security API. Inject a SecurityContext instance into the [hotspot=22-50 file=0]`HomeServlet` class. The [hotspot=33-40 file=0]`doGet()` method uses the [hotspot=35-36 file=0]`isCallerInRole()` method from SecurityContext API to check a user's role and then forwards the response to the appropriate page.

Open the `src/main/webapp/WEB-INF/web.xml` file and look at the rest of the security declaration for the application:
The [hotspot=24-55 file=1]`src/main/webapp/WEB-INF/web.xml` file contains the rest of the security declaration for the application.

[source, xml, indent=0, role="no_copy"]
web.xml
[source, xml, linenums, role="code_column"]
----
include::finish/src/main/webapp/WEB-INF/web.xml[tags=webxmlsecurity]
include::finish/src/main/webapp/WEB-INF/web.xml[tags=webxml;!copyright]
----

The `<security-role>` elements define the roles supported by the application, which are `user` and `admin`. The `<security-constraint>` elements further specify that JSF resources like the `user.jsf` and `admin.jsf` pages can only be accessed by users with `user` and `admin` role respectively.
The [hotspot=25-31 file=1]`<security-role/>` elements define the roles supported by the application, which are [hotspot=30 file=1]`user` and [hotspot=26 file=1]`admin`. The [hotspot=34-55 file=1]`<security-constraint/>` elements further specify that JSF resources like the [hotspot=48 file=1]`user.jsf` and [hotspot=37 file=1]`admin.jsf` pages can only be accessed by users with [hotspot=30 file=1]`user` and [hotspot=26 file=1]`admin` role respectively.

// =================================================================================================
// Configuring the user registry
Expand All @@ -137,36 +146,42 @@ User registries store user account information, such as username and password, f

Open Liberty provides an easy-to-use basic user registry for developers, which you will configure.

Create the `src/main/liberty/config/userRegistry.xml` file:
[role="code_command hotspot", subs="quotes"]
----
#Create the `UserRegistry` configuration file.#
`src/main/liberty/config/userRegistry.xml`
----

[source, xml, indent=0]
userRegistry.xml
[source, xml, linenums, role="code_column"]
----
include::finish/src/main/liberty/config/userRegistry.xml[tags=**]
----

The registry has four users, `bob`, `alice`, `carl` and `dave`, and four groups, `Employee`, `TeamLead`, `Manager` and `PartTime`. Each user belongs to one or more groups.
The registry has four users, [hotspot=13 file=0]`bob`, [hotspot=21 file=0]`alice`, [hotspot=23 file=0]`carl` and [hotspot=27 file=0]`dave`, and four groups, [hotspot=20-24 file=0]`Employee`, [hotspot=16-18 file=0]`TeamLead`, [hotspot=12-14 file=0]`Manager` and [hotspot=26-28 file=0]`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 using the Liberty `securityUtility` command with XOR encoding.
It is not recommended to store passwords in plain text. The passwords in the [hotspot file=0]`userRegistry.xml` file are encoded using the Liberty `securityUtility` command with XOR encoding.

Open the `server.xml` file to view the security configuration of the server.
The [hotspot=19-27 file=1]`server.xml` file contains the security configuration of the server.

[source, xml, indent=0, role="no_copy"]
server.xml
[source, xml, linenums, role="code_column"]
----
include::finish/src/main/liberty/config/server.xml[tags=serverxmlsecurity]
include::finish/src/main/liberty/config/server.xml[tags=**]
----

Use the `<include>` element to add the basic user registry configuration to your server configuration. Open Liberty will include configuration information from the specified XML file in its server configuration.
Use the [hotspot=13 file=1]`<include/>` element to add the basic user registry configuration to your server configuration. Open Liberty will include configuration information from the specified XML file in its server configuration.

Map the groups in the user registry 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 using the `<security-role>` and `<group>` elements under the `<application-bnd>` configuration.
Map the groups in the user registry to the appropriate user roles supported by the application for proper user authorization. The [hotspot=21 file=1]`Manager` and [hotspot=22 file=1]`TeamLead` groups are mapped to the [hotspot=20 file=1]`admin` role while the [hotspot=25 file=1]`Employee` group is mapped to the [hotspot=24 file=1]`user` role using the [hotspot=20-26 file=1]`<security-role/>` and [hotspot=21-22 file=1]`<group/>` elements under the [hotspot=19-27 file=1]`<application-bnd/>` configuration.


// =================================================================================================
// Building and running the application
// =================================================================================================

[role="command"]
include::{common-includes}/mvnbuild.adoc[]

Point your browser to `http://localhost:9080`. As you can see, the browser gets redirected from an HTTP connection to an HTTPS connection automatically, which is due to the transport guarantee defined in the `HomeServlet` class.
Point your browser to http://localhost:9080[http://localhost:9080^]. As you can see, the browser gets redirected from an HTTP connection to an HTTPS connection automatically, which is due to the transport guarantee defined in the `HomeServlet` class.

You will see a login form since form authentication is implemented and configured. Sign into the application using one of the credentials from the following table, which is defined in the configured user registry.

Expand Down Expand Up @@ -199,6 +214,7 @@ When you sign in as Alice, you can only view Alice's name.
When you sign in as Dave, you'll be blocked and will see a `Error 403: Authorization failed` message because Dave doesn't have a role supported by the application.

Once you're done checking out the application, log out and stop the Open Liberty server:
[role='command']
```
mvn liberty:stop-server
```
Expand All @@ -211,17 +227,23 @@ mvn liberty:stop-server

Write `SecurityTest` class to test the authentication and authorization of the application.

Create the `SecurityTest` class in the `src/test/java/it/io/openliberty/guides/security/SecurityTest.java` file like the following:
[role="code_command hotspot", subs="quotes"]
----
#Create the `SecurityTest` class.#
`src/test/java/it/io/openliberty/guides/security/SecurityTest.java`
----

[source, java, indent=0]
SecurityTest.java
[source, java, linenums, role="code_column"]
----
include::finish/src/test/java/it/io/openliberty/guides/security/SecurityTest.java[tags=test]
include::finish/src/test/java/it/io/openliberty/guides/security/SecurityTest.java[tags=**;!copyright]
----

The `testAuthenticationFail()` method tests an invalid user authentication while the `testAuthorizationFail()` method tests unauthorized access to the application.
The [hotspot=40-42]`testAuthenticationFail()` method tests an invalid user authentication while the [hotspot=57-60]`testAuthorizationFail()` method tests unauthorized access to the application.

The `testAuthorizationForAdmin()` and `testAuthorizationForUser()` methods, respectively, verify that a user with `admin` role and a user with `user` role are properly authenticated and can access authorized resource.
The [hotspot=45-48]`testAuthorizationForAdmin()` and [hotspot=51-54]`testAuthorizationForUser()` methods, respectively, verify that a user with `admin` role and a user with `user` role are properly authenticated and can access authorized resource.

[role="command"]
include::{common-includes}/mvnverify.adoc[]

[source, role="no_copy"]
Expand All @@ -245,9 +267,9 @@ Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

== Great work! You're done!

You learned how to use Java EE Security to authenticate and authorize users to secure your web application.
You learned how to use Java EE Security in Open Liberty to authenticate and authorize users to secure your web application.

Next, you can try the related https://openliberty.io/guides/microprofile-jwt.html[MicroProfile JWT] guide. It demonstrates technologies to secure backend services.
Next, you can try the related https://openliberty.io/guides/microprofile-jwt.html[MicroProfile JWT^] guide. It demonstrates technologies to secure backend services.


include::{common-includes}/finish.adoc[]
include::{common-includes}/attribution.adoc[subs="attributes"]
Loading

0 comments on commit 2de8132

Please sign in to comment.