Using single sign-on with JBoss EAP Red Hat JBoss Enterprise Application Platform 8.0 Guide to using single sign-on to add authentication to applications deployed on JBoss EAP Red Hat Customer Content Services

Commands:
mvn archetype:generate -DgroupId= USD{group-to-which-your-application-belongs} -DartifactId= USD{name-of-your-application} -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
cd <name-of-your-application>
cd simple-webapp-example
<?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>USD{project.artifactId}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>USD{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>
mvn install
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.795 s [INFO] Finished at: 2022-04-28T17:39:48+05:30 [INFO] ------------------------------------------------------------------------
mkdir -p src/main/java/<path_based_on_artifactID>
mkdir -p src/main/java/com/example/app
cd src/main/java/<path_based_on_artifactID>
cd src/main/java/com/example/app
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>"); } } }
mvn package [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.015 s [INFO] Finished at: 2022-04-28T17:48:53+05:30 [INFO] ------------------------------------------------------------------------
mvn wildfly:deploy
Secured Servlet Current Principal 'NO AUTHENTICATED USER'
<path_to_rhbk> /bin/kc.sh start-dev --http-port <offset-number>
/home/servers/rhbk-22.0/bin/kc.sh start-dev --http-port 8180
<login-config> <auth-method>OIDC</auth-method> </login-config>
{ "client-id" : "customer-portal", 1 "provider-url" : "http://localhost:8180/realms/demo", 2 "ssl-required" : "external", 3 "credentials" : { "secret" : "234234-234234-234234" 4 } }
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0"> <secure-deployment name="DEPLOYMENT_RUNTIME_NAME.war"> 1 <client-id>customer-portal</client-id> 2 <provider-url>http://localhost:8180/realms/demo</provider-url> 3 <ssl-required>external</ssl-required> 4 <credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" /> 5 </secure-deployment </subsystem>
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0"> <provider name=" USD{OpenID_provider_name} "> <provider-url>http://localhost:8080/realms/demo</provider-url> <ssl-required>external</ssl-required> </provider> <secure-deployment name="customer-portal.war"> 1 <provider> USD{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"> 2 <provider> USD{OpenID_provider_name} </provider> <client-id>product-portal</client-id> <credential name="secret" secret="0aa31d98-e0aa-404c-b6e0-e771dba1e798" /> </secure-deployment> </subsystem>
realm: example_realm
auth-server-url: http://localhost:8180/
ssl-required: external
resource: jbeap-oidc
public-client: yes
confidential-port: 0
"provider-url" : "http://localhost:8180/realms/example_realm", "ssl-required": "external", "client-id": "jbeap-oidc", "public-client": true, "confidential-port": 0
<?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>
<web-app> <login-config> <auth-method>OIDC</auth-method> 1 </login-config> </web-app>
provider-url: http://localhost:8180/realms/example_realm
ssl-required: external
client-id: jbeap-oidc
public-client: yes
confidential-port: 0
/subsystem=elytron-oidc-client/secure-deployment=simple-oidc-example.war/:add(client-id=jbeap-oidc,provider-url=http://localhost:8180/realms/example_realm,public-client=true,ssl-required=external)
mvn package
mvn wildfly:deploy
<login-config> <auth-method>SAML</auth-method> </login-config>
<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>
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
Can't reset to root in the middle of the path @72
<?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>
<web-app> <login-config> <auth-method>SAML</auth-method> 1 </login-config> </web-app>
<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>
/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/SP=""/:add(sslPolicy=EXTERNAL,logoutPage="SPECIFY YOUR LOGOUT PAGE!"
<EAP_HOME> /bin/jboss-cli.sh -c --file=<path_to_the_file>/keycloak-saml-subsystem.cli
mvn wildfly:deploy
/subsystem=elytron/virtual-security-domain= <deployment_name> :add()
/subsystem=elytron/virtual-security-domain=simple-ear-example.ear:add()
@SecurityDomain(" <deployment_name> ")
@SecurityDomain("simple-ear-example.ear") @Remote(RemoteHello.class) @Stateless public class RemoteHelloBean implements RemoteHello { @Resource private SessionContext context; @Override public String whoAmI() { return context.getCallerPrincipal().getName(); } }
mvn wildfly:deploy
/subsystem=elytron/virtual-security-domain= <deployment_name> :add(outflow-security-domains=[ <domain_to_propagate_to> ])
/subsystem=elytron/virtual-security-domain=simple-ear-example.ear:add(outflow-security-domains=[exampleEJBSecurityDomain])
/subsystem=elytron/security-domain= <security_domain_name> :write-attribute(name=trusted-virtual-security-domains,value=[ <deployment_name> ])
/subsystem=elytron/security-domain=exampleEJBSecurityDomain:write-attribute(name=trusted-virtual-security-domains,value=[simple-ear-example.ear])
reload
mvn wildfly:deploy
/subsystem=elytron-oidc-client/provider=keycloak:add(provider-url= <OIDC_provider_URL> )
/subsystem=elytron-oidc-client/provider=keycloak:add(provider-url=http://localhost:8180/realms/example_jboss_infra)
/subsystem=elytron-oidc-client/secure-deployment=wildfly-management:add(provider= <OIDC_provider_name> ,client-id= <OIDC_client_name> ,principal-attribute= <attribute_to_use_as_principal> ,bearer-only=true,ssl-required= <internal_or_external> )
/subsystem=elytron-oidc-client/secure-deployment=wildfly-management:add(provider=keycloak,client-id=jboss-management,principal-attribute=preferred_username,bearer-only=true,ssl-required=EXTERNAL)
/core-service=management/access=authorization:write-attribute(name=provider,value=rbac) /core-service=management/access=authorization:write-attribute(name=use-identity-roles,value=true)
/subsystem=elytron-oidc-client/secure-server=wildfly-console:add(provider= <OIDC_provider_name> ,client-id= <OIDC_client_name> ,public-client=true)
/subsystem=elytron-oidc-client/secure-server=wildfly-console:add(provider=keycloak,client-id=jboss-console,public-client=true)