Chapter 2. Securing applications deployed on JBoss EAP with Single Sign-On
You can secure applications with Single Sign-on (SSO) to delegate authentication to an SSO-provider such as Red Hat build of Keycloak. You can use either OpenID Connect (OIDC) or Security Assertion Markup Language v2 (SAML v2) as the SSO protocols.
To secure applications with SSO, follow these procedures:
- Create an example application to secure with Single sign-on: Use this procedure to create a simple web-application for securing with SSO. If you already have an application to secure with SSO, skip this step.
- Create a realm and users in Red Hat build of Keycloak
Secure your application with SSO by using either OIDC or SAML as the protocol:
2.1. Creating an example application to secure with Single sign-on
Create a web-application to deploy on JBoss EAP and secure it with Single sign-on (SSO) with OpenID Connect (OIDC) or Security Assertion Mark-up Language (SAML).
The following procedures are provided as an example only. If you already have an application that you want to secure, you can skip these and go directly to Creating a realm and users in Red Hat build of Keycloak.
2.1.1. Creating a Maven project for web-application development
For creating a web-application, create a Maven project with the required dependencies and the directory structure.
The following procedure is provided only as an example and should not be used in a production environment. For information about creating applications for JBoss EAP, see Getting started with developing applications for JBoss EAP deployment.
Prerequisites
- You have installed Maven. For more information, see Downloading Apache Maven.
Procedure
Set up a Maven project using the
mvn
command. The command creates the directory structure for the project and thepom.xml
configuration file.Syntax
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn archetype:generate \ -DgroupId=${group-to-which-your-application-belongs} \ -DartifactId=${name-of-your-application} \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false
$ mvn archetype:generate \ -DgroupId=${group-to-which-your-application-belongs} \ -DartifactId=${name-of-your-application} \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false
Example
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn archetype:generate \ -DgroupId=com.example.app \ -DartifactId=simple-webapp-example \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false
$ mvn archetype:generate \ -DgroupId=com.example.app \ -DartifactId=simple-webapp-example \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false
Navigate to the application root directory:
Syntax
Copy to Clipboard Copied! Toggle word wrap Toggle overflow cd <name-of-your-application>
$ cd <name-of-your-application>
Example
Copy to Clipboard Copied! Toggle word wrap Toggle overflow cd simple-webapp-example
$ cd simple-webapp-example
Replace the content of the generated
pom.xml
file with the following text:Copy to Clipboard Copied! Toggle word wrap Toggle overflow <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.app</groupId> <artifactId>simple-webapp-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>simple-webapp-example Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <version.maven.war.plugin>3.4.0</version.maven.war.plugin> </properties> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>${version.maven.war.plugin}</version> </plugin> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>4.2.2.Final</version> </plugin> </plugins> </build> </project>
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.app</groupId> <artifactId>simple-webapp-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>simple-webapp-example Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <version.maven.war.plugin>3.4.0</version.maven.war.plugin> </properties> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>${version.maven.war.plugin}</version> </plugin> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>4.2.2.Final</version> </plugin> </plugins> </build> </project>
Verification
In the application root directory, enter the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn install
$ mvn install
You get an output similar to the following:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.795 s [INFO] Finished at: 2022-04-28T17:39:48+05:30 [INFO] ------------------------------------------------------------------------
... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.795 s [INFO] Finished at: 2022-04-28T17:39:48+05:30 [INFO] ------------------------------------------------------------------------
Next steps
2.1.2. Creating a web application
Create a web application containing a servlet that returns the user name obtained from the logged-in user’s principal. If there is no logged-in user, the servlet returns the text "NO AUTHENTICATED USER".
In this procedure, <application_home> refers to the directory that contains the pom.xml
configuration file for the application.
Prerequisites
You have created a Maven project.
For more information, see Creating a Maven project for web-application development.
- JBoss EAP is running.
Procedure
Create a directory to store the Java files.
Syntax
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mkdir -p src/main/java/<path_based_on_artifactID>
$ mkdir -p src/main/java/<path_based_on_artifactID>
Example
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mkdir -p src/main/java/com/example/app
$ mkdir -p src/main/java/com/example/app
Navigate to the new directory.
Syntax
Copy to Clipboard Copied! Toggle word wrap Toggle overflow cd src/main/java/<path_based_on_artifactID>
$ cd src/main/java/<path_based_on_artifactID>
Example
Copy to Clipboard Copied! Toggle word wrap Toggle overflow cd src/main/java/com/example/app
$ cd src/main/java/com/example/app
Create a file
SecuredServlet.java
with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow package com.example.app; import java.io.IOException; import java.io.PrintWriter; import java.security.Principal; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; /** * A simple secured HTTP servlet. It returns the user name of obtained * from the logged-in user's Principal. If there is no logged-in user, * it returns the text "NO AUTHENTICATED USER". */ @WebServlet("/secured") public class SecuredServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (PrintWriter writer = resp.getWriter()) { writer.println("<html>"); writer.println(" <head><title>Secured Servlet</title></head>"); writer.println(" <body>"); writer.println(" <h1>Secured Servlet</h1>"); writer.println(" <p>"); writer.print(" Current Principal '"); Principal user = req.getUserPrincipal(); writer.print(user != null ? user.getName() : "NO AUTHENTICATED USER"); writer.print("'"); writer.println(" </p>"); writer.println(" </body>"); writer.println("</html>"); } } }
package com.example.app; import java.io.IOException; import java.io.PrintWriter; import java.security.Principal; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; /** * A simple secured HTTP servlet. It returns the user name of obtained * from the logged-in user's Principal. If there is no logged-in user, * it returns the text "NO AUTHENTICATED USER". */ @WebServlet("/secured") public class SecuredServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (PrintWriter writer = resp.getWriter()) { writer.println("<html>"); writer.println(" <head><title>Secured Servlet</title></head>"); writer.println(" <body>"); writer.println(" <h1>Secured Servlet</h1>"); writer.println(" <p>"); writer.print(" Current Principal '"); Principal user = req.getUserPrincipal(); writer.print(user != null ? user.getName() : "NO AUTHENTICATED USER"); writer.print("'"); writer.println(" </p>"); writer.println(" </body>"); writer.println("</html>"); } } }
In the application root directory, compile your application with the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn package
$ mvn package ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.015 s [INFO] Finished at: 2022-04-28T17:48:53+05:30 [INFO] ------------------------------------------------------------------------
Deploy the application.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn wildfly:deploy
$ mvn wildfly:deploy
Verification
In a browser, navigate to
http://localhost:8080/simple-webapp-example/secured
.You get the following message:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Secured Servlet Current Principal 'NO AUTHENTICATED USER'
Secured Servlet Current Principal 'NO AUTHENTICATED USER'
Because no authentication mechanism is added, you can access the application.
2.2. Creating a realm and users in Red Hat build of Keycloak
A realm in Red Hat build of Keycloak is equivalent to a tenant. Each realm allows an administrator to create isolated groups of applications and users.
The following procedure outlines the minimum steps required to get started with securing applications deployed to JBoss EAP with Red Hat build of Keycloak for testing purposes. For detailed configurations, see the Red Hat build of Keycloak Server Administration Guide.
The following procedure is provided as an example only. If you already have configured a realm and users in Red Hat build of Keycloak, you can skip this procedure and go directly to securing applications. For more information, see:
Prerequisites
- You have administrator access to Red Hat build of Keycloak.
Procedure
Start the Red Hat build of Keycloak server at a port other than 8080 because JBoss EAP default port is 8080.
NoteThe
start-dev
command is not meant for production environments. For more information, see Trying Red Hat build of Keycloak in development mode in the Red Hat build of Keycloak Server Guide.Syntax
Copy to Clipboard Copied! Toggle word wrap Toggle overflow <path_to_rhbk>/bin/kc.sh start-dev --http-port <offset-number>
$ <path_to_rhbk>/bin/kc.sh start-dev --http-port <offset-number>
Example
Copy to Clipboard Copied! Toggle word wrap Toggle overflow /home/servers/rhbk-22.0/bin/kc.sh start-dev --http-port 8180
$ /home/servers/rhbk-22.0/bin/kc.sh start-dev --http-port 8180
-
Log in to the Admin Console at
http://localhost:<port>/
. For example,http://localhost:8180/
. Create a realm.
- Hover over Master, and click Create Realm.
-
Enter a name for the realm. For example,
example_realm
. - Ensure that Enabled is set to ON.
- Click Create.
For more information, see Creating a realm in the Red Hat build of Keycloak Server Administration Guide.
Create a user.
- Click Users, then click Add user,
-
Enter a user name. For example,
user1
. - Click Create.
For more information, see Creating users in the Red Hat build of Keycloak Server Administration Guide.
Set credentials for the user.
- Click Credentials.
-
Set a password for the user. For example,
passwordUser1
. Toggle Temporary to OFF and click Set Password. In the confirmation prompt, click Save.
For more information, see Defining user credentials in the Red Hat build of Keycloak Server Administration Guide.
Create a role.
This is the role name you configure in JBoss EAP for authorization.
- Click Realm Roles, then Create role.
- Enter a role name, such as Admin.
- Click Save.
Assign the role to the user.
- Click Users.
- Click the user to which you want to assign the role.
- Click Role Mapping.
- Click Assign role.
- Select the role to assign. For example, Admin. Click Assign.
For more information, see Creating a realm role in the Red Hat build of Keycloak Server Administration Guide.
Next steps
To use this realm to secure applications deployed to JBoss EAP, follow these procedures:
Additional resources
2.3. Securing applications with OIDC
Use the JBoss EAP native OpenID Connect (OIDC) client to secure your applications using an external OpenID provider. OIDC is an identity layer that enables clients, such as JBoss EAP, to verify a user’s identity based on authentication performed by an OpenID provider. For example, you can secure your JBoss EAP applications using Red Hat build of Keycloak as the OpenID provider.
To secure applications with OIDC, follow these procedures:
2.3.1. Application security with OpenID Connect in JBoss EAP
When you secure your applications using an OpenID provider, you do not need to configure any security domain resources locally. The elytron-oidc-client
subsystem provides a native OpenID Connect (OIDC) client in JBoss EAP to connect with OpenID providers (OP). JBoss EAP automatically creates a virtual security domain for your application, based on your OpenID provider configurations. The elytron-oidc-client
subsystem acts as the Relying Party (RP).
The JBoss EAP native OIDC client does not support RP-Initiated logout.
It is recommended to use the OIDC client with Red Hat build of Keycloak. You can use other OpenID providers if they can be configured to use access tokens that are JSON Web Tokens (JWTs) and can be configured to use the RS256, RS384, RS512, ES256, ES384, or ES512 signature algorithm.
To enable the use of OIDC, you can configure either the elytron-oidc-client
subsystem or an application itself. JBoss EAP activates the OIDC authentication as follows:
-
When you deploy an application to JBoss EAP, the
elytron-oidc-client
subsystem scans the deployment to detect if the OIDC authentication mechanism is required. -
If the subsystem detects OIDC configuration for the deployment in either the
elytron-oidc-client
subsystem or the application deployment descriptor, JBoss EAP enables the OIDC authentication mechanism for the application. -
If the subsystem detects OIDC configuration in both places, the configuration in the
elytron-oidc-client
subsystemsecure-deployment
attribute takes precedence over the configuration in the application deployment descriptor.
Deployment configuration
To secure an application with OIDC by using a deployment descriptor, update the application’s deployment configuration as follows:
-
Set the
auth-method
property toOIDC
in the application deployment descriptorweb.xml
file.
Example deployment descriptor update
<login-config> <auth-method>OIDC</auth-method> </login-config>
<login-config>
<auth-method>OIDC</auth-method>
</login-config>
Create a file called
oidc.json
in theWEB-INF
directory with the OIDC configuration information.Example
oidc.json
contentsCopy to Clipboard Copied! Toggle word wrap Toggle overflow { "client-id" : "customer-portal", "provider-url" : "http://localhost:8180/realms/demo", "ssl-required" : "external", "credentials" : { "secret" : "234234-234234-234234" } }
{ "client-id" : "customer-portal",
1 "provider-url" : "http://localhost:8180/realms/demo",
2 "ssl-required" : "external",
3 "credentials" : { "secret" : "234234-234234-234234"
4 } }
Subsystem configuration
You can secure applications with OIDC by configuring the elytron-oidc-client
subsystem in the following ways:
- Create a single configuration for multiple deployments if you use the same OpenID provider for each application.
- Create a different configuration for each deployment if you use different OpenID providers for different applications.
Example XML configuration for a single deployment:
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0"> <secure-deployment name="DEPLOYMENT_RUNTIME_NAME.war"> <client-id>customer-portal</client-id> <provider-url>http://localhost:8180/realms/demo</provider-url> <ssl-required>external</ssl-required> <credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" /> </secure-deployment </subsystem>
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0">
<secure-deployment name="DEPLOYMENT_RUNTIME_NAME.war">
<client-id>customer-portal</client-id>
<provider-url>http://localhost:8180/realms/demo</provider-url>
<ssl-required>external</ssl-required>
<credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" />
</secure-deployment
</subsystem>
To secure multiple applications using the same OpenID provider, configure the provider
separately, as shown in the example:
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0"> <provider name="${OpenID_provider_name}"> <provider-url>http://localhost:8080/realms/demo</provider-url> <ssl-required>external</ssl-required> </provider> <secure-deployment name="customer-portal.war"> <provider>${OpenID_provider_name}</provider> <client-id>customer-portal</client-id> <credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" /> </secure-deployment> <secure-deployment name="product-portal.war"> <provider>${OpenID_provider_name}</provider> <client-id>product-portal</client-id> <credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" /> </secure-deployment> </subsystem>
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0">
<provider name="${OpenID_provider_name}">
<provider-url>http://localhost:8080/realms/demo</provider-url>
<ssl-required>external</ssl-required>
</provider>
<secure-deployment name="customer-portal.war">
<provider>${OpenID_provider_name}</provider>
<client-id>customer-portal</client-id>
<credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" />
</secure-deployment>
<secure-deployment name="product-portal.war">
<provider>${OpenID_provider_name}</provider>
<client-id>product-portal</client-id>
<credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" />
</secure-deployment>
</subsystem>
Additional resources
2.3.2. Creating an OIDC client in Red Hat build of Keycloak
Create an OpenID Connect (OIDC) client in Red Hat build of Keycloak to use with JBoss EAP to secure applications.
The following procedure outlines the minimum steps required to get started with securing applications deployed to JBoss EAP with Red Hat build of Keycloak for testing purposes. For detailed configurations, see Managing OpenID Connect clients in the Red Hat build of Keycloak Server Administration Guide.
Prerequisites
You have created a realm and defined users in Red Hat build of Keycloak.
For more information, see Creating a realm and users in JBoss EAP
Procedure
- Navigate to the Red Hat build of Keycloak Admin Console.
Create a client.
- Click Clients, then click Create client.
-
Ensure that Client type is set to
OpenID Connect
. -
Enter a client ID. For example,
jbeap-oidc
. - Click Next.
- In the Capability Config tab, ensure that Authentication Flow is set to Standard flow and Direct access grants.
- Click Next.
-
In the Login settings tab, enter the value for Valid redirect URIs. Enter the URL where the page should redirect after successful authentication, for example,
http://localhost:8080/simple-webapp-example/secured/*
. - Click Save.
View the adapter configuration.
- Click Action, then Download adapter config.
Select
Keycloak OIDC JSON
as the Format Option to see the connection parameters.Copy to Clipboard Copied! Toggle word wrap Toggle overflow { "realm": "example_realm", "auth-server-url": "http://localhost:8180/", "ssl-required": "external", "resource": "jbeap-oidc", "public-client": true, "confidential-port": 0 }
{ "realm": "example_realm", "auth-server-url": "http://localhost:8180/", "ssl-required": "external", "resource": "jbeap-oidc", "public-client": true, "confidential-port": 0 }
When configuring your JBoss EAP application to use Red Hat build of Keycloak as the identity provider, you use the parameters as follows:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow "provider-url" : "http://localhost:8180/realms/example_realm", "ssl-required": "external", "client-id": "jbeap-oidc", "public-client": true, "confidential-port": 0
"provider-url" : "http://localhost:8180/realms/example_realm", "ssl-required": "external", "client-id": "jbeap-oidc", "public-client": true, "confidential-port": 0
Additional resources
2.3.3. Securing a web application using OpenID Connect
You can secure an application by either updating its deployment configuration or by configuring the elytron-oidc-client subsystem
.
If you use the application created in the procedure, Creating a web application, the value of the Principal comes from the ID token from the OpenID provider. By default, the Principal is the value of the "sub" claim from the token. You can also use the value of “email”, “preferred_username”, “name”, “given_name”, “family_name”, or “nickname” claims as the Principal. Specify which claim value from the ID token is to be used as the Principal in one of the following places:
-
The
elytron-oidc-client
subsystem attributeprincipal-attribute
. -
The oidc.json file
.
There are two ways in which you can configure applications to use OIDC:
By configuring the
elytron-oidc-client
subsystem.Use this method if you do not want to add configuration to the application deployment.
By updating the deployment configuration
Use this method if you do not want to add configuration to the server and prefer to keep the configuration within the application deployment.
Prerequisites
- You have deployed applications on JBoss EAP.
Procedure
Configure the application’s
web.xml
to protect the application resources.Copy to Clipboard Copied! Toggle word wrap Toggle overflow <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="false"> <security-constraint> <web-resource-collection> <web-resource-name>secured</web-resource-name> <url-pattern>/secured</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>*</role-name> </security-role> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="false"> <security-constraint> <web-resource-collection> <web-resource-name>secured</web-resource-name> <url-pattern>/secured</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name>
1 </auth-constraint> </security-constraint> <security-role> <role-name>*</role-name> </security-role> </web-app>
- 1
- Only allow the users with the role
Admin
to access the application. To allow users with any role to access the application, use the wildcard**
as the value forrole-name
.
To secure the application with OpenID Connect, either update the deployment configuration or configure the
elytron-oidc-client
subsystem.NoteIf you configure OpenID Connect in both the deployment configuration and the
elytron-oidc-client
subsystem, the configuration in theelytron-oidc-client
subsystemsecure-deployment
attribute takes precedence over the configuration in the application deployment descriptor.Updating the deployment configuration.
Add login configuration to the application’s
web.xml
specifying authentication method as OIDC.Copy to Clipboard Copied! Toggle word wrap Toggle overflow <web-app> ... <login-config> <auth-method>OIDC</auth-method> </login-config> ... </web-app>
<web-app> ... <login-config> <auth-method>OIDC</auth-method>
1 </login-config> ... </web-app>
- 1
- Use OIDC to secure the application.
Create a file
oidc.json
in theWEB-INF
directory, like this:Copy to Clipboard Copied! Toggle word wrap Toggle overflow { "provider-url" : "http://localhost:8180/realms/example_realm", "ssl-required": "external", "client-id": "jbeap-oidc", "public-client": true, "confidential-port": 0 }
{ "provider-url" : "http://localhost:8180/realms/example_realm", "ssl-required": "external", "client-id": "jbeap-oidc", "public-client": true, "confidential-port": 0 }
Configuring the
elytron-oidc-client
subsystem:To secure your application, use the following management CLI command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow /subsystem=elytron-oidc-client/secure-deployment=simple-webapp-example.war/:add(client-id=jbeap-oidc,provider-url=http://localhost:8180/realms/example_realm,public-client=true,ssl-required=external)
/subsystem=elytron-oidc-client/secure-deployment=simple-webapp-example.war/:add(client-id=jbeap-oidc,provider-url=http://localhost:8180/realms/example_realm,public-client=true,ssl-required=external)
In the application root directory, compile your application with the following command:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn package
$ mvn package
Deploy the application.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn wildfly:deploy
$ mvn wildfly:deploy
Verification
In a browser, navigate to
http://localhost:8080/simple-webapp-example/secured
.You are redirected to Red Hat build of Keycloak login page.
- You can log in with your credentials for the user you defined in Red Hat build of Keycloak.
Your application is now secured using OIDC.
Additional resources
2.4. Securing applications with SAML
You can use the Galleon layers provided by the Keycloak SAML adapter feature pack to secure web applications with Security Assertion Markup Language (SAML).
For information about Keycloak SAML adapter feature pack, see Keycloak SAML adapter feature pack for securing applications using SAML.
To secure applications with SAML, follow these procedures:
2.4.1. Application security with SAML in JBoss EAP
Keycloak SAML adapter Galleon pack is a Galleon feature pack that includes three layers: keycloak-saml
, keycloak-client-saml
, and keycloak-client-saml-ejb
. Use the layers in the feature pack to install the necessary modules and configurations in JBoss EAP to use Red Hat build of Keycloak as an identity provider for single sign-on using Security Assertion Markup Language (SAML).
The following table describes the use cases for each layer.
Layer | Applicable for | Description |
---|---|---|
| OpenShift |
Use this layer for Source to Image (s2i) with automatic registration of the SAML client. You must use this layer along with the |
| Bare metal, OpenShift |
Use this layer for web-applications on bare metal, and for Source to Image (s2i) with |
| Bare metal | Use this layer for applications where you want to propagate identities to Jakarta Enterprise Beans. |
To enable the use of SAML, you can configure either the keycloak-saml
subsystem or an application itself.
Deployment configuration
To secure an application with SAML by using a deployment descriptor, update the application’s deployment configuration as follows:
Set the
auth-method
property toSAML
in the application deployment descriptorweb.xml
file.Example deployment descriptor update
Copy to Clipboard Copied! Toggle word wrap Toggle overflow <login-config> <auth-method>SAML</auth-method> </login-config>
<login-config> <auth-method>SAML</auth-method> </login-config>
Create a file called
keycloak-saml.xml
in theWEB-INF
directory with the SAML configuration information. You can obtain this file from the SAML provider.Example
keycloak-saml.xml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow <keycloak-saml-adapter> <SP entityID="" sslPolicy="EXTERNAL" logoutPage="SPECIFY YOUR LOGOUT PAGE!"> <Keys> <Key signing="true"> <PrivateKeyPem>PRIVATE KEY NOT SET UP OR KNOWN</PrivateKeyPem> <CertificatePem>...</CertificatePem> </Key> </Keys> <IDP entityID="idp" signatureAlgorithm="RSA_SHA256" signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"> <SingleSignOnService signRequest="true" validateResponseSignature="true" validateAssertionSignature="false" requestBinding="POST" bindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> <SingleLogoutService signRequest="true" signResponse="true" validateRequestSignature="true" validateResponseSignature="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml" redirectBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> </IDP> </SP> </keycloak-saml-adapter>
<keycloak-saml-adapter> <SP entityID="" sslPolicy="EXTERNAL" logoutPage="SPECIFY YOUR LOGOUT PAGE!"> <Keys> <Key signing="true"> <PrivateKeyPem>PRIVATE KEY NOT SET UP OR KNOWN</PrivateKeyPem> <CertificatePem>...</CertificatePem> </Key> </Keys> <IDP entityID="idp" signatureAlgorithm="RSA_SHA256" signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"> <SingleSignOnService signRequest="true" validateResponseSignature="true" validateAssertionSignature="false" requestBinding="POST" bindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> <SingleLogoutService signRequest="true" signResponse="true" validateRequestSignature="true" validateResponseSignature="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml" redirectBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> </IDP> </SP> </keycloak-saml-adapter>
The values of
PrivateKeyPem
, andCertificatePem
are unique for each client.
Subsystem configuration
You can secure applications with SAML by configuring the keycloak-saml
subsystem. You can obtain the client configuration file containing the subsystem configuration commands from Red Hat build of Keycloak. For more information, see Generating client adapter config.
2.4.2. Creating a SAML client in Red Hat build of Keycloak
Create a Security Assertion Markup Language (SAML) client in Red Hat build of Keycloak to use with JBoss EAP to secure applications.
The following procedure outlines the minimum steps required to get started with securing applications deployed to JBoss EAP with Red Hat build of Keycloak for testing purposes. For detailed configurations, see Creating a SAML client in the Red Hat build of Keycloak Server Administration Guide.
Prerequisites
You have created a realm and defined users in Red Hat build of Keycloak.
For more information, see Creating a realm and users in JBoss EAP
Procedure
- Navigate to the Red Hat build of Keycloak Admin Console.
Create a client.
- Click Clients, then click Create client.
- Select SAML as the Client type.
Enter the URL for the application you want to secure as the Client ID. For example,
http://localhost:8080/simple-webapp-example/secured/
.ImportantThe client ID must exactly match the URL of your application. If the client ID does not match, you get an error similar to the following:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 2023-05-17 19:54:31,586 WARN [org.keycloak.events] (executor-thread-0) type=LOGIN_ERROR, realmId=eba0f106-389f-4216-a676-05fcd0c0c72e, clientId=null, userId=null, ipAddress=127.0.0.1, error=client_not_found, reason=Cannot_match_source_hash
2023-05-17 19:54:31,586 WARN [org.keycloak.events] (executor-thread-0) type=LOGIN_ERROR, realmId=eba0f106-389f-4216-a676-05fcd0c0c72e, clientId=null, userId=null, ipAddress=127.0.0.1, error=client_not_found, reason=Cannot_match_source_hash
-
Enter a client name. For example,
jbeap-saml
. - Click Next.
Enter the following information:
-
Root URL: The URL for your application, for example,
http://localhost:8080/simple-webapp-example/
. Home URL: The URL for your application, for example,
http://localhost:8080/simple-webapp-example/
.ImportantIf you do not set the Home URL,
SP entityID
in the client configuration remains blank and causes errors.If using the management CLI commands, you get the following error:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Can't reset to root in the middle of the path @72
Can't reset to root in the middle of the path @72
You can resolve the error by defining the value for
SP entityID
in the respective configuration files.-
Valid Redirect URIs: The URIs that are allowed after a user logs in, for example,
http://localhost:8080/simple-webapp-example/secured/*
. Master SAML Processing URL: The URL for your application followed by
saml
. For example,http://localhost:8080/simple-webapp-example/saml
.ImportantIf you do not append
saml
to the URL, you get a redirection error.For more information, see Creating a SAML client.
-
Root URL: The URL for your application, for example,
You can now use the configured client to secure web applications deployed on JBoss EAP. For more information, see Securing web applications using SAML.
Next steps
Additional resources
2.4.3. Securing web applications using SAML
The Keycloak SAML adapter feature pack provides two layers for non-OpenShift deployments: keycloak-client-saml
, and keycloak-client-saml-ejb
. Use the keycloak-client-saml
layer to secure servlet based-web applications, and the keycloak-client-saml-ejb
to secure Jakarta Enterprise Beans applications.
There are two ways in which you can configure applications to use SAML:
By configuring the
keycloak-saml
subsystem.Use this method if you do not want to add configuration to the application deployment.
By updating the deployment configuration
Use this method if you do not want to add configuration to the server and prefer to keep the configuration within the application deployment.
Prerequisites
A SAML client has been created in Red Hat build of Keycloak.
For more information, see Creating a SAML client in Red Hat build of Keycloak.
JBoss EAP has been installed by using the
jboss-eap-installation-manager
.For more information, see Installing JBoss EAP 8.0 using the
jboss-eap-installation-manager
in the Red Hat JBoss Enterprise Application Platform Installation Methods guide.
Procedure
Add the required Keycloak SAML adapter layer to the server by using
jboss-eap-installation-manager
. Following are the details of the available layers:-
Feature pack:
org.keycloak:keycloak-saml-adapter-galleon-pack
. Layers:
-
keycloak-client-saml
: Use this layer to secure servlets. keycloak-client-saml-ejb
: Use this layer to propagate identities from servlets to Jakarta Enterprise Beans.For information about adding feature packs and layers in JBoss EAP, see Adding Feature Packs to existing JBoss EAP Servers using the jboss-eap-installation-manager in the Red Hat JBoss Enterprise Application Platform Installation Methods guide.
-
-
Feature pack:
Configure the application’s
web.xml
to protect the application resources.Copy to Clipboard Copied! Toggle word wrap Toggle overflow <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="false"> <security-constraint> <web-resource-collection> <web-resource-name>secured</web-resource-name> <url-pattern>/secured</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>*</role-name> </security-role> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="false"> <security-constraint> <web-resource-collection> <web-resource-name>secured</web-resource-name> <url-pattern>/secured</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name>
1 </auth-constraint> </security-constraint> <security-role> <role-name>*</role-name> </security-role> </web-app>
- 1
- Only allow the users with the role
Admin
to access the application. To allow users with any role to access the application, use the wildcard**
as the value forrole-name
.
Secure your applications with SAML either by using the management CLI, or by updating the application deployment.
By updating the application deployment.
Add login configuration to the application’s
web.xml
specifying authentication method as SAML.Copy to Clipboard Copied! Toggle word wrap Toggle overflow <web-app> ... <login-config> <auth-method>SAML</auth-method> </login-config> ... </web-app>
<web-app> ... <login-config> <auth-method>SAML</auth-method>
1 </login-config> ... </web-app>
- 1
- Use SAML to secure the application.
Download the configuration
keycloak-saml.xml
file from Red Hat build of Keycloak and save it in theWEB-INF/
directory of your application.For more information, see Generating client adapter config.
Example
keycloak-saml.xml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow <keycloak-saml-adapter> <SP entityID="" sslPolicy="EXTERNAL" logoutPage="SPECIFY YOUR LOGOUT PAGE!"> <Keys> <Key signing="true"> <PrivateKeyPem>PRIVATE KEY NOT SET UP OR KNOWN</PrivateKeyPem> <CertificatePem>...</CertificatePem> </Key> </Keys> <IDP entityID="idp" signatureAlgorithm="RSA_SHA256" signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"> <SingleSignOnService signRequest="true" validateResponseSignature="true" validateAssertionSignature="false" requestBinding="POST" bindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> <SingleLogoutService signRequest="true" signResponse="true" validateRequestSignature="true" validateResponseSignature="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml" redirectBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> </IDP> </SP> </keycloak-saml-adapter>
<keycloak-saml-adapter> <SP entityID="" sslPolicy="EXTERNAL" logoutPage="SPECIFY YOUR LOGOUT PAGE!"> <Keys> <Key signing="true"> <PrivateKeyPem>PRIVATE KEY NOT SET UP OR KNOWN</PrivateKeyPem> <CertificatePem>...</CertificatePem> </Key> </Keys> <IDP entityID="idp" signatureAlgorithm="RSA_SHA256" signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#"> <SingleSignOnService signRequest="true" validateResponseSignature="true" validateAssertionSignature="false" requestBinding="POST" bindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> <SingleLogoutService signRequest="true" signResponse="true" validateRequestSignature="true" validateResponseSignature="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml" redirectBindingUrl="http://localhost:8180/realms/example_saml_realm/protocol/saml"/> </IDP> </SP> </keycloak-saml-adapter>
The values of
PrivateKeyPem
, andCertificatePem
are unique for each client.
By using the management CLI.
Download the client configuration file
keycloak-saml-subsystem.cli
from Red Hat build of Keycloak.For more information, see Generating client adapter config.
Example
keycloak-saml-subsystem.cli
Copy to Clipboard Copied! Toggle word wrap Toggle overflow /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/:add /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/:add(sslPolicy=EXTERNAL,logoutPage="SPECIFY YOUR LOGOUT PAGE!" /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/Key=KEY1:add(signing=true, \ PrivateKeyPem="...", CertificatePem="...") /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/IDP=idp/:add( \ SingleSignOnService={ \ signRequest=true, \ validateResponseSignature=true, \ validateAssertionSignature=false, \ requestBinding=POST, \ bindingUrl=http://localhost:8180/realms/example-saml-realm/protocol/saml}, \ SingleLogoutService={ \ signRequest=true, \ signResponse=true, \ validateRequestSignature=true, \ validateResponseSignature=true, \ requestBinding=POST, \ responseBinding=POST, \ postBindingUrl=http://localhost:8180/realms/example-saml-realm/protocol/saml, \ redirectBindingUrl=http://localhost:8180/realms/example-saml-realm/protocol/saml} \ ) /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/IDP=idp/:write-attribute(name=signatureAlgorithm,value=RSA_SHA256) /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/IDP=idp/:write-attribute(name=signatureCanonicalizationMethod,value=http://www.w3.org/2001/10/xml-exc-c14n#)
/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/:add /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/:add(sslPolicy=EXTERNAL,logoutPage="SPECIFY YOUR LOGOUT PAGE!" /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/Key=KEY1:add(signing=true, \ PrivateKeyPem="...", CertificatePem="...") /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/IDP=idp/:add( \ SingleSignOnService={ \ signRequest=true, \ validateResponseSignature=true, \ validateAssertionSignature=false, \ requestBinding=POST, \ bindingUrl=http://localhost:8180/realms/example-saml-realm/protocol/saml}, \ SingleLogoutService={ \ signRequest=true, \ signResponse=true, \ validateRequestSignature=true, \ validateResponseSignature=true, \ requestBinding=POST, \ responseBinding=POST, \ postBindingUrl=http://localhost:8180/realms/example-saml-realm/protocol/saml, \ redirectBindingUrl=http://localhost:8180/realms/example-saml-realm/protocol/saml} \ ) /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/IDP=idp/:write-attribute(name=signatureAlgorithm,value=RSA_SHA256) /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP="http://localhost:8080/simple-webapp-example/"/IDP=idp/:write-attribute(name=signatureCanonicalizationMethod,value=http://www.w3.org/2001/10/xml-exc-c14n#)
The values of
PrivateKeyPem
, andCertificatePem
are unique for each client.Update every occurrence of
YOUR-WAR.war
in the client configuration file with the name of your application WAR, for examplesimple-webapp-example.war
.NoteThe generated CLI script has a missing
)
at the end of the second statement:Copy to Clipboard Copied! Toggle word wrap Toggle overflow /subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=""/:add(sslPolicy=EXTERNAL,logoutPage="SPECIFY YOUR LOGOUT PAGE!"
/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=""/:add(sslPolicy=EXTERNAL,logoutPage="SPECIFY YOUR LOGOUT PAGE!"
You must add the missing
)
Configure JBoss EAP by running
keycloak-saml-subsystem.cli
script using the management CLI.Copy to Clipboard Copied! Toggle word wrap Toggle overflow <EAP_HOME>/bin/jboss-cli.sh -c --file=<path_to_the_file>/keycloak-saml-subsystem.cli
$ <EAP_HOME>/bin/jboss-cli.sh -c --file=<path_to_the_file>/keycloak-saml-subsystem.cli
Deploy the application.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow mvn wildfly:deploy
$ mvn wildfly:deploy
Verification
In a browser, navigate to the application URL. For example,
http://localhost:8080/simple-webapp-example/secured
.You are redirected to the Red Hat build of Keycloak login page.
- You can log in with your credentials for the user you defined in Red Hat build of Keycloak.
Your application is now secured using SAML.
Additional resources