1 2 Previous Next 18 Replies Latest reply on Dec 9, 2018 6:52 PM by Christoph John Branched from an earlier discussion.

    OAuth with KeyCloak

    Christoph John Newbie

      Hello Ramesh,

      I have some problems with the description to build the keycloak teiid adapters for oauth and do not get it running. I followed

       

      OAuth2 Based Security For OData Using KeyCloak · GitBook

       

      to build the teiid-odata-oauth-keycloak module. I would only like to build the authentication for this module, hence, I do assume that I do not require the passthrough option that is described in the tutorial.

       

      When building the module for keycloak 4.5 und teiid 11.2.0 I configured

       

      teiid-web-security/pom.xml at master · teiid/teiid-web-security · GitHub

       

      the following way:

       

        <properties>

            <version.org.keycloak>4.5.0.Final</version.org.keycloak>

            <version.org.jboss.teiid>11.2.0</version.org.jboss.teiid>

              <apache.httpcomponents.version>4.3.6</apache.httpcomponents.version>

              <resteasy.version>2.3.7.Final</resteasy.version>

          </properties>

       

      Unfortunately, I just get an dependency error:

       

      Failed to execute goal on project teiid-odata-oauth-keycloak: Could not resolve dependencies for project org.jboss.teiid:teiid-odata-oauth-keycloak:jar:0.0.1-SNAPSHOT: Could not find artifact org.jboss.teiid:teiid-api:jar:11.2.0 in central (https://repo.maven.apache.org/maven2) -> [Help 1]

       

      Can you tell me which version strings I have to use here and how I can set the probably required additional repositories? I assume for httpcomponents and resteasy I also have to take different versions.

       

      Furthermore, I am also wondering, if I can simply skip the configuration part for the passthrough part according to the tutorial. This currently is my assumption. Is this assumption correct? I mean this part here:

       

       

      ./bin/jboss-cli.sh --connect /subsystem=security/security-domain=passthrough:add(cache-type=default) /subsystem=security/security-domain=passthrough/authentication=classic:add /subsystem=security/security-domain=passthrough/authentication=classic/login-module=passthrough:add(code=org.teiid.jboss.PassthroughIdentityLoginModule, flag=required, module=org.jboss.teiid)  reload

       

      above commands will result in XML in standalone.xml or domain.xml file like (you can also edit standalone.xml directly)

       

          <security-domain name="passthrough"> <authentication> <login-module code="org.teiid.jboss.PassthroughIdentityLoginModule" flag="required" module="org.jboss.teiid"/> </authentication> </security-domain>
        • 1. Re: OAuth with KeyCloak
          Ramesh Reddy Master

          For the build error change the groug id to org.teiid:teiid-api

           

          Then follow, we need to change the document.

           

          Ramesh  

          • 2. Re: OAuth with KeyCloak
            Ramesh Reddy Master

            Btw, you can probably use latest versions of keycloak .

            • 3. Re: OAuth with KeyCloak
              Christoph John Newbie

              Hello Ramesh,

              I now upgraded keycloak to the 4.6 version and got the  teiid-web-security/odata-oauth-keycloak module build with the following config options, hence I just changed the groug id to org.teiid:teiid-api. My sources are available here GitHub - cjohn001/teiid-web-security: OData Web Application with different security profiles

               

                    <properties>

                          <version.org.keycloak>4.6.0.Final</version.org.keycloak>

                          <version.org.jboss.teiid>11.2.0</version.org.jboss.teiid>

                      <apache.httpcomponents.version>4.3.6</apache.httpcomponents.version>

                      <resteasy.version>2.3.7.Final</resteasy.version>

                  </properties>

               

              My first question: Is it correct to use version 4.3.6 and 2.3.7 for httpcomponents and resteasy or do I need to modify the pom.xml here to take more recent versions  of these modules?

               

              When copying the file to Teiid the authorization is unfortunately not running yet.

               

              The keycloak configuration that I provided for the odata-oauth-keycloak module is the following:

               

               

              {

                "realm": "mnd",

                "realm-public-key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArFn7fxR9gYavb4Z5H79ZRjL8VDzV4dwkX1Nx1E8zfy3YL5CAQxWP2Ah+VW+pWknUJFx13WCG4rN2h20YeCILI74TtAHZ2I3IrN3rdrZlPVEklxxpQzIEC+I1zAxS2Wrh8MwNLFGL9fkydgKGmKXerZxW5SH2ojv3Rc2Jzty0ztZsLujT1lQkYxctYmsk6vY7GwDbBx6gbao8LrTX/UnSq8jynqmpRuRINCevrdpJzcRiI6lejOQa3oZcBEdBL6xLEOkI+rA4z592eYbI/rp+QsTMlJ2C0hw5ZH5fZStmLY2YUQnHLzPMuSroH0YM7S1mPyR8LjfgHoTAkAVJIzH5aQIDAQAB",

                "auth-server-url": "https://localhost:8443/auth",

                "ssl-required": "all",

                "resource": "Teiid",

                "credentials": {

                  "secret": "blablabla"

                }

              }

               

              I have to mention, that I have not added the passthrough stuff in the configuration, as I do not have a service to which I want to pass the token through. Hence the following is not in my configuration:

               

              <init-param>
                 <param-name>PassthroughAuthentication</param-name>
                 <param-value>true</param-value>
                 </init-param>

               

              When the module is loaded in Wildfly, I get the following errors. I am not very familiar with java. However, do I interpret it right, that I am missing dependencies here?

               

                 Caused by: java.lang.NoClassDefFoundError: org/keycloak/adapters/ServerRequest$HttpFailure

                 Caused by: java.lang.ClassNotFoundException: org.keycloak.adapters.ServerRequest$HttpFailure from [Module \"deployment.teiid-olingo-odata4.war\" from Service Module Loader]"}}

               

              If so, how can I fix this?

               

               

               

               

              22:26:20,410 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1)  MSC000001: Failed to start service jboss.deployment.unit."teiid-olingo-odata4.war".POST_MODULE: org.jboss.msc.service.StartException in service jboss.deployment.unit."teiid-olingo-odata4.war".POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment "teiid-olingo-odata4.war"

                at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:172)

                at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:2032)

                at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1955)

                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

                at java.lang.Thread.run(Thread.java:748)

              Caused by: java.lang.RuntimeException: WFLYSRV0177: Error getting reflective information for class org.teiid.oauth.keycloak.AuthServlet with ClassLoader ModuleClassLoader for Module "deployment.teiid-olingo-odata4.war" from Service Module Loader

                at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:78)

                at org.jboss.as.ee.metadata.MethodAnnotationAggregator.runtimeAnnotationInformation(MethodAnnotationAggregator.java:57)

                at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.handleAnnotations(InterceptorAnnotationProcessor.java:106)

                at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:91)

                at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:76)

                at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:165)

                ... 5 more

              Caused by: java.lang.NoClassDefFoundError: org/keycloak/adapters/ServerRequest$HttpFailure

                at java.lang.Class.getDeclaredFields0(Native Method)

                at java.lang.Class.privateGetDeclaredFields(Class.java:2583)

                at java.lang.Class.getDeclaredFields(Class.java:1916)

                at org.jboss.as.server.deployment.reflect.ClassReflectionIndex.<init>(ClassReflectionIndex.java:72)

                at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:70)

                ... 10 more

              Caused by: java.lang.ClassNotFoundException: org.keycloak.adapters.ServerRequest$HttpFailure from [Module "deployment.teiid-olingo-odata4.war" from Service Module Loader]

                at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198)

                at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:412)

                at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:400)

                at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)

                ... 15 more

               

              22:26:20,684 INFO  [org.teiid.RUNTIME] (MSC service thread 1-3)  TEIID50012 Teiid JDBC - Name = jdbc, Host = localhost,  Port = 31000, SSL = OFF

              22:26:20,693 INFO  [org.teiid.RUNTIME] (MSC service thread 1-4)  TEIID50037 Teiid ODBC - Name = odbc, Host = localhost,  Port = 35432, SSL = OFF

              22:26:20,698 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread)  WFLYCTL0013: Operation ("add") failed - address: ([("deployment" => "teiid-olingo-odata4.war")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"teiid-olingo-odata4.war\".POST_MODULE" => "WFLYSRV0153: Failed to process phase POST_MODULE of deployment \"teiid-olingo-odata4.war\"

                  Caused by: java.lang.RuntimeException: WFLYSRV0177: Error getting reflective information for class org.teiid.oauth.keycloak.AuthServlet with ClassLoader ModuleClassLoader for Module \"deployment.teiid-olingo-odata4.war\" from Service Module Loader

                  Caused by: java.lang.NoClassDefFoundError: org/keycloak/adapters/ServerRequest$HttpFailure

                  Caused by: java.lang.ClassNotFoundException: org.keycloak.adapters.ServerRequest$HttpFailure from [Module \"deployment.teiid-olingo-odata4.war\" from Service Module Loader]"}}

              22:26:20,738 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 59)  WFLYSRV0010: Deployed "teiid-olingo-odata4.war" (runtime-name : "teiid-olingo-odata4.war")

              22:26:20,752 INFO  [org.jboss.as.controller] (Controller Boot Thread)  WFLYCTL0183: Service status report

              WFLYCTL0186:   Services which failed to start:      service jboss.deployment.unit."teiid-olingo-odata4.war".POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment "teiid-olingo-odata4.war"

               

              22:26:20,926 INFO  [org.jboss.as.server] (Controller Boot Thread)  WFLYSRV0212: Resuming server

              22:26:20,929 INFO  [org.jboss.as] (Controller Boot Thread)  WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management

              22:26:20,929 INFO  [org.jboss.as] (Controller Boot Thread)  WFLYSRV0051: Admin console listening on http://127.0.0.1:9990

              22:26:20,929 ERROR [org.jboss.as] (Controller Boot Thread)  WFLYSRV0026: WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final) started (with errors) in 12352ms - Started 548 of 853 services (1 services failed or missing dependencies, 460 services are lazy, passive or on-demand)

              • 4. Re: OAuth with KeyCloak
                Ramesh Reddy Master

                I can't really comment on version updates as individual products may have changed from when we tested with versions mentioned in the article.

                 

                Basically you install Keycloak server in one instance and install a adapter in teiid wildfly server, and your web app talks to the Keycloak through the adapter. In this case from error I see that the version of Keycloak you installed and adapter installed do not match. They must be from same Keycloak version. I see java is complaining about some classes missing. So reinstall Keycloak adapter that matches your Keycloak server. Also use same in build too.

                 

                Ramesh ..

                • 5. Re: OAuth with KeyCloak
                  Christoph John Newbie

                  Hello Ramesh,

                  I double checked the versions and I am definitely using keycloak 4.6.0 as a server, as an adapter for Wildfly 11.0.0 and in the odata-oauth-keycloak module. I found that using the

                   

                  adapter-elytron-install.cli

                   

                  script made things somehow better. But I have still a remaining error I cannot resolve, which is

                   

                  >>Required services that are not installed:" => ["jboss.security.security-domain.keycloak"],

                   

                  I have added the keycloak security domain, see below command marked in red. I would have expected that this does the trick. However, seems I do not understand what is going on here.

                   

                  To make things more easy to follow, here is  my Wildfly Dockerfile. Sources for the odata-oauth-keycloak module are the same like in my last post.

                   

                  ******************************************************************************************************************************************************************************************************************************************************

                  FROM jboss/wildfly:11.0.0.Final

                  ENV TEIID_VERSION 11.2.0

                  ENV JBOSS_HOME /opt/jboss/wildfly

                  ENV JBOSS_CLI /opt/jboss/wildfly/bin/jboss-cli.sh

                   

                   

                  # Copy and unzip Teiid server

                  COPY --chown=jboss:jboss teiid-$TEIID_VERSION-wildfly-dist.zip $JBOSS_HOME

                  RUN cd $JBOSS_HOME \

                      && bsdtar -xf teiid-$TEIID_VERSION-wildfly-dist.zip \

                      && chmod +x $JBOSS_HOME/bin/*.sh \

                      && rm teiid-$TEIID_VERSION-wildfly-dist.zip

                   

                   

                  # add required admin and application user

                  RUN echo "=> Adding WildFly administrator and application user" \

                      && $JBOSS_HOME/bin/add-user.sh -u 'test' -p 'test' -g 'admin' \

                      && $JBOSS_HOME/bin/add-user.sh -a -u 'test' -p 'test' -g 'odata,rest'

                   

                   

                  # add keycloak adapter

                  COPY --chown=jboss:jboss keycloak-wildfly-adapter-dist-4.6.0.Final.zip $JBOSS_HOME

                  RUN echo "=> Adding Keycloak adapter" \

                      && cd $JBOSS_HOME \

                      && bsdtar -xf keycloak-wildfly-adapter-dist-4.6.0.Final.zip \

                      && rm keycloak-wildfly-adapter-dist-4.6.0.Final.zip

                   

                  # configure keycloak adapter

                  RUN echo "=> Starting WildFly server" \

                      && bash -c '$JBOSS_HOME/bin/standalone.sh -c standalone-teiid.xml &' \

                      && echo "=> Waiting for the server to boot" \

                      && bash -c 'until `$JBOSS_CLI -c ":read-attribute(name=server-state)" 2> /dev/null | grep -q running`; do echo `$JBOSS_CLI -c ":read-attribute(name=server-state)" 2> /dev/null`; sleep 1; done' \

                      && echo "=> Configuring Keycloak adapter" \

                      && $JBOSS_CLI --connect --file=$JBOSS_HOME/bin/adapter-elytron-install.cli \

                      && $JBOSS_CLI --connect --command="/subsystem=teiid:write-attribute(name=authentication-security-domain, value=keycloak)" \

                      && $JBOSS_CLI --connect --command="/:reload" \

                      && echo "=> Shutting down WildFly and Cleaning up" \

                      && $JBOSS_CLI --connect --command=":shutdown"

                   

                  # add keycloak oauth2 service module

                  COPY --chown=jboss:jboss teiid-web-security/odata-oauth-keycloak/target/teiid-odata-oauth-keycloak-0.0.1-SNAPSHOT.war \

                      $JBOSS_HOME/modules/system/layers/dv/org/jboss/teiid/main/deployments/teiid-olingo-odata4.war

                   

                  # copy sql driver

                  ENV MYSQL_VERSION 8.0.13

                  COPY --chown=jboss:jboss  mysql-connector-java-${MYSQL_VERSION}.jar  /tmp/mysql-connector-java-${MYSQL_VERSION}.jar

                   

                  # Configure Wildfly server with mysql driver

                  # Database

                  ENV DB_NAME my_nutri_diary

                  ENV DB_USER test

                  ENV DB_PASS test

                  ENV DB_URI db:3306

                   

                  RUN echo "=> Starting WildFly server" \

                      && bash -c '$JBOSS_HOME/bin/standalone.sh -c standalone-teiid.xml &' \

                      && echo "=> Waiting for the server to boot" \

                      && bash -c 'until `$JBOSS_CLI -c ":read-attribute(name=server-state)" 2> /dev/null | grep -q running`; do echo `$JBOSS_CLI -c ":read-attribute(name=server-state)" 2> /dev/null`; sleep 1; done' \

                      && echo "=> Adding MySQL module" \

                      && $JBOSS_CLI --connect --command="module add --name=com.mysql --resources=/tmp/mysql-connector-java-${MYSQL_VERSION}.jar --dependencies=javax.api,javax.transaction.api" \

                      && echo "=> Adding MySQL driver" \

                      && $JBOSS_CLI --connect --command="/subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql,driver-module-name=com.mysql,driver-class-name=com.mysql.cj.jdbc.Driver)" \

                      && echo "=> Creating a new datasource" \

                      && $JBOSS_CLI --connect --command="data-source add \

                      --name=${DB_NAME} \

                      --jndi-name=java:/${DB_NAME} \

                      --user-name=${DB_USER} \

                      --password=${DB_PASS} \

                      --driver-name=mysql \

                      --connection-url=jdbc:mysql://${DB_URI}/${DB_NAME} \

                      --use-ccm=false \

                      --max-pool-size=25 \

                      --blocking-timeout-wait-millis=5000 \

                      --enabled=true" \

                      && echo "=> Setting CORS headers" \

                      && $JBOSS_CLI --connect --command="/subsystem=undertow/configuration=filter/response-header=Access-Control-Allow-Origin:add(header-name=Access-Control-Allow-Origin,header-value=*)" \

                      && $JBOSS_CLI --connect --command="/subsystem=undertow/server=default-server/host=default-host/filter-ref=Access-Control-Allow-Origin:add" \

                      && echo "=> Shutting down WildFly and Cleaning up" \

                      && $JBOSS_CLI --connect --command=":shutdown" \

                      && rm -rf $JBOSS_HOME/standalone/configuration/standalone_xml_history/ $JBOSS_HOME/standalone/log/* \

                      && rm -f /tmp/*.jar

                   

                  # Deploy VDB

                  COPY --chown=jboss:jboss ./my_nutri_diary_model/views/svc-vdb.xml $JBOSS_HOME/standalone/deployments

                  COPY --chown=jboss:jboss ./my_nutri_diary_model/views/svc-vdb.xml.dodeploy $JBOSS_HOME/standalone/deployments

                  USER jboss

                   

                  ENV LAUNCH_JBOSS_IN_BACKGROUND true

                   

                  # Expose Teiid server  ports

                  EXPOSE 8080 9990 31000 35432

                   

                  # Run Teiid server and bind to all interface

                  CMD ["/bin/sh", "-c", "$JBOSS_HOME/bin/standalone.sh -c standalone-teiid.xml -b 0.0.0.0 -bmanagement 0.0.0.0"]

                   

                  ******************************************************************************************************************************************************************************************************************************************************

                   

                  22:30:18,691 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread)  WFLYCTL0013: Operation ("add") failed - address: ([("deployment" => "teiid-olingo-odata4.war")]) - failure description: {

                      "WFLYCTL0412: Required services that are not installed:" => ["jboss.security.security-domain.keycloak"],

                      "WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.undertow.deployment.default-server.default-host./odata4.UndertowDeploymentInfoService is missing [jboss.security.security-domain.keycloak]"]

                  }

                  22:30:18,718 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 60)  WFLYSRV0010: Deployed "teiid-olingo-odata4.war" (runtime-name : "teiid-olingo-odata4.war")

                  22:30:18,719 INFO  [org.jboss.as.controller] (Controller Boot Thread)  WFLYCTL0183: Service status report

                  WFLYCTL0184:    New missing/unsatisfied dependencies:

                        service jboss.security.security-domain.keycloak (missing) dependents: [service jboss.undertow.deployment.default-server.default-host./odata4.UndertowDeploymentInfoService]

                   

                  22:30:18,861 INFO  [org.jboss.as.server] (Controller Boot Thread)  WFLYSRV0212: Resuming server

                  22:30:18,866 INFO  [org.jboss.as] (Controller Boot Thread)  WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management

                  22:30:18,867 INFO  [org.jboss.as] (Controller Boot Thread)  WFLYSRV0051: Admin console listening on http://127.0.0.1:9990

                  22:30:18,867 ERROR [org.jboss.as] (Controller Boot Thread)  WFLYSRV0026: WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final) started (with errors) in 13533ms - Started 666 of 942 services (3 services failed or missing dependencies, 466 services are lazy, passive or on-demand)

                  • 6. Re: OAuth with KeyCloak
                    Ramesh Reddy Master

                    Looks like Wildfly 11 changed how the security domain is created? Did you try this on standalone server before the Docker to see any errors? Did it add the Keycloak security domain to standalone-teiid XML file.

                     

                    Ramesh.

                    • 7. Re: OAuth with KeyCloak
                      Christoph John Newbie

                      Hello Ramesh,

                      it looks like the security domain was added. I did not get any error messages and the section according to your tutorial

                       

                      <authentication security-domain="keycloak"/>
                         <transport name="odata"/>

                       

                      is included in the standalone/teiid.xml. I uploaded the resulting file under the following link:

                       

                      teiid-web-security/standalone-teiid.xml at master · cjohn001/teiid-web-security · GitHub

                       

                      However, what looks a little bit weired for me is that I find security domains in different places in the config. There is one in a so called subsection elytron  (search for KeycloakDomain)

                      and the one I have added under subsection teiid. I do not knwo how things look if they work, hence it is difficult for me to make a correct statement here.

                       

                      Christoph

                      • 8. Re: OAuth with KeyCloak
                        Christoph John Newbie

                        Hello Ramesh,

                        ok, I made some progress. To my current understanding it seems that Wildfly supports two security subsystems elytron and the predecessor subsystem which your plugin seems to be using. I am now using the adapter-install.cli script again instead of the adapter-elytron-install.cli script. Looks like I made a mistake in the Dockerfile when I was using the adapter-install.cli in the past. At least now it does the job. With it, I am now able to load the odata-oauth-keycloak module. My browser is now correctly forwarded to the keycloak login page when I hit an odata url. However, I still do not see the odata page after login and instead get a redirect error. I assume this is due to a wrong configuration of keycloak. Seems like it forwards everyting to https and port 0 irrespective of how I configure keycloak. The urls look like this one https://localhost:0/odata4/svc/my_nutri_diary/$metadata?state=...

                         

                        I just would like to let  you know that you do not need to investigate time in the security domain issue. If I should not get further from here I will come back on you. Thx.

                        • 9. Re: OAuth with KeyCloak
                          Christoph John Newbie

                          Hello Ramsh,

                          seems to become a nightmare. In the meantime I do not believe anymore in a konfiguration issue with keycloak. When I open an odata page I am redirected to the keycloak login page and can provide credentials. Afterwords I am redirected to the odata page but I do get only a web page telling me "Forbidden". I think the redirect uri looks fine, even though I cannot interprete and validate the parameters.

                           

                          http://localhost:8080/odata4/svc/my_nutri_diary/$metadata?state=91e255a2-520c-4571-9d21-6f3dfd5a6a0d&session_state=26e80…

                           

                          However, in the server log I see the following errors which I do not understand. I am really wondering that I seem to get ssl errors here as I am using http protocol. My login page is connected via https (the first redirect for login, might be that the errors arrise there?)

                           

                           

                          ERROR [org.keycloak.adapters.OAuthRequestAuthenticator] (default task-2)  failed to turn code into token: javax.net.ssl.SSLHa

                          ndshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: u

                          nable to find valid certification path to requested target

                            at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)

                            at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)

                            at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)

                            at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)

                            at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)

                            at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)

                            at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)

                            at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)

                            at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)

                            at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)

                            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)

                            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)

                            at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:553)

                            at org.keycloak.adapters.SniSSLSocketFactory.connectSocket(SniSSLSocketFactory.java:109)

                            at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:412)

                            at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:179)

                            at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144)

                            at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134)

                            at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:612)

                            at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)

                            at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)

                            at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)

                            at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)

                            at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)

                            at org.keycloak.adapters.ServerRequest.invokeAccessCodeToToken(ServerRequest.java:111)

                            at org.keycloak.adapters.OAuthRequestAuthenticator.resolveCode(OAuthRequestAuthenticator.java:335)

                            at org.keycloak.adapters.OAuthRequestAuthenticator.authenticate(OAuthRequestAuthenticator.java:280)

                            at org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:139)

                            at org.keycloak.adapters.undertow.AbstractUndertowKeycloakAuthMech.keycloakAuthenticate(AbstractUndertowKeycloakAuthMech.java:110)

                            at org.keycloak.adapters.undertow.ServletKeycloakAuthMech.authenticate(ServletKeycloakAuthMech.java:92)

                            at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:245)

                            at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:263)

                            at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:231)

                            at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:125)

                            at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:99)

                            at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:92)

                            at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)

                            at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33)

                            at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                            at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53)

                            at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)

                            at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:6

                          4)

                            at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59)

                            at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)

                            at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)

                            at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)

                            at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)

                            at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                            at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)

                            at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                            at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)

                            at org.keycloak.adapters.undertow.ServletPreAuthActionsHandler.handleRequest(ServletPreAuthActionsHandler.java:69)

                            at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

                            at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)

                            at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)

                            at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)

                            at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)

                            at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)

                            at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)

                            at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)

                            at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoSe

                          rvice.java:1508)

                            at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoSe

                          rvice.java:1508)

                            at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoSe

                          rvice.java:1508)

                            at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoSe

                          rvice.java:1508)

                            at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)

                            at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)

                            at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)

                            at io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)

                            at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)

                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

                            at java.lang.Thread.run(Thread.java:748)

                          Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable t

                          o find valid certification path to requested target

                            at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)

                            at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)

                            at sun.security.validator.Validator.validate(Validator.java:262)

                            at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)

                            at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)

                            at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)

                            at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)

                            ... 67 more

                          Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

                            at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)

                            at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)

                            at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)

                            at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)

                            ... 73 more

                          • 10. Re: OAuth with KeyCloak
                            Christoph John Newbie

                            Hello Ramesh,

                            as more I am reading about the Wildfly security configuration, as more I am convinced that I should use the elytron adapter for security. This is because the old security model seems to be deprecated. I am wondering what direction is best to go for me to configure Wildfly with Teiid. I have not resolved my configuration issue according to my previous question yet. However, as there seems to exist two directions to deal with the issue, I would like to ask for your advice what direction to go from here. I do not want to end up with a partial solution which does not support row-based security at the end of the day. Besides the pure authentication via the keycloak realm I also need Teiids row-based security for database access. With it I mean, I plan to have a mapping table called

                             

                            Account: with the columns

                            - Keycloak UUID (char 36)

                            - ProfileID (unsigned bigint)

                             

                            as I want to use the ProfileID as a foreign key in all my database tables, rather than the Keycloak UUID, due to performance and memory space considerations. For read and write access via odata, than the server should map the  Keycloak UUID of the client, given alongside with the client request in the access token, to the ProfileID of the respective user, and compare it with a foreignKey of the ProfileID in the table of the requested data. For example, if I have a table

                             

                            Data, with columns

                            - user name

                            - user"s age

                            - ProfileID (Foreign key of ProfileID in table Accounts)

                             

                            a read or write request on a data set (select * from Data where ProfileID=xyz) should trigger the server to check access privileges by mapping the received  Keycloak UUID to the respective ProfileID, compare it with the ProfileID in the row of the Data table and provide or deny access. As far as I understood, this kind of row-based security is supported by teiid via a configuration in the vdb. I do not have an understanding on how to configure these things in the vdb yet, or even on how this functionality is internally implemented. However, for the moment I am wondering, if this kind of functionality needs to use functionality of the Wildfly security subsystem, for example to deal with the UUID in the access token, or if the functionality is independent of it and is completely implemented within the Teiid subsystem.

                            Hence, my question is, if these things will work independently of the wildfly security subsystem (elytron or the old one) wich I will use? Or do I have to stick with the old security subsystem to get things running?

                            Thanks for your advice!

                            • 11. Re: OAuth with KeyCloak
                              Ramesh Reddy Master

                              Christoph,

                               

                              I have not looked at Elytron subsystem in WildFly so far, IMO it should not matter if you use the new subsystem vs old, as these are just used only for Authentication. For Authrorization, Teiid depends on "role" information, which is tied to "scopes" in OAuth. However, if you do use Elytron, as you found you would need to update the scripts to make use of it.

                               

                              Teiid defines the RBAC based model, where you define roles in your VDB and assign data permissions to it as to which role has which permissions. The Teiid requires a mapping between roles defined in the VDB vs enterprise user roles, i.e. your OAuth scopes. When a user logs with certain scopes then data is provided or denied based on user's allowed scopes. So, yes it is completely independent, it does not deal directly with Keycloak UUID. By this way we can map to LDAP or any custom auth/autz provider.

                               

                              See Data Roles · GitBook

                               

                               

                              As per your exception, I believe in the new KeyCloak they provided a login screen and redirect automatically, this was not the case in previous versions, thus some tasks in odata-oauth-keycloak mimic these. So, you can ignore odata-oauth-keycloak and follow this https://www.keycloak.org/docs/latest/securing_apps/index.html#jboss-eap-wildfly-adapter  where you just modify web.xml of odata war file in Teiid and provide keycloak.json file and that should be it.

                               

                              Ramesh..

                              • 12. Re: OAuth with KeyCloak
                                Christoph John Newbie

                                Hello Ramesh,

                                thanks for the feedback. I found the data roles topic in the meantime and I am currently reading through it. And I also found a solution for the Keycloak topic. I do not use the odata-oauth-keycloak module anymore and I found a solution which even does not require modifiying the odata web.xml file. There seem to be two directions to configure keycloak, per service module, which requires adaption of the web.xml file. I assume the approach you have linked, and a global approach, where one just needs to edit the standalone-teiid.xml. The later approach now works for me. I think the error which I have seen belongs somewho to ssl configuration and certificate checking. For the moment I have just disabled it, via disable-trust-manager, see command below. I will look at this topic later on. My solution is quite simple. I just added the following commands to my docker file.

                                 

                                 

                                && echo "=> Configuring Keycloak adapter" \

                                    && $JBOSS_CLI --connect --file=$JBOSS_HOME/bin/adapter-install.cli \

                                    && echo "=> Adding realm" \

                                    && $JBOSS_CLI --connect --command="/subsystem=keycloak/realm=mnd:add(realm-public-key=MI......B, auth-server-url=https://keycloak.imsproject.svc.cluster.local:8443/auth,ssl-required=none, disable-trust-     manager=true)" \

                                    && echo "=> Adding Teiid ressource" \

                                    && $JBOSS_CLI --connect --command="/subsystem=keycloak/secure-deployment=teiid-olingo-odata4.war:add(realm=mnd,resource=Teiid)" \

                                    && echo "=> Adding credentials" \

                                    && $JBOSS_CLI --connect --command="/subsystem=keycloak/secure-deployment=teiid-olingo-odata4.war/credential=secret:add(value=8b.....5)" \

                                #    && echo "=> Writing keycloak security domain" \

                                #    && $JBOSS_CLI --connect --command="/subsystem=teiid:write-attribute(name=authentication-security-domain, value=keycloak)" \

                                    && echo "=> reload started" \

                                    && $JBOSS_CLI --connect --command="/:reload" \

                                 

                                So I hope this does the trick. What I currently do not understand is, if and how the odata module obtains the uuid from the access-token as I just started with reading. I have seen one can write a user() function in the vdb.xml file, see http://teiid.github.io/teiid-documents/10.2.x/teiid-documents.pdf  page 501. I hope this will provide the users uuid from the access token, as I will need this to define the Data Roles when comparing the user against an entry in the database to allow access. Well, I hope it will just work .

                                 

                                I am not sure if I understand this correct with the roles. Do you say that the row based security also only depends on the realm roles / oauth scopes? This means I will not be able to limit a users access to the data rows that belongs to him?

                                 

                                I mean I would for example just like to let an user add a data row if he adds his uuid to the row and just would like to allow him updates of rows data that belong to him. This will not work if I cannot access his uuid. I cannot give a dedicated role to each user. So does this mean I cannot configure the functionality I intend and have to write an own backend for this?

                                In this case I would not understand why the documentation speaks about row level security. If I cannot access the uuid directly yet, would it be possible to add this feature? I am planning to used teiid in an SPA where the javascript source is accessible in the browser. Hence I need to ensure that a logged in user can only edit his data and can only add datasets which contain his uuid.

                                • 13. Re: OAuth with KeyCloak
                                  Ramesh Reddy Master

                                  On the configuration, note the default WAR file has the "basic" auth, hopefully, the centralized the configuration does override that. On UUID, the security subsystem based the authentication provides a "login context" where one can glean the user information, Teiid's user() function makes use of that. As per controlling the data based on user, that is not row level security, rather a "column level" data masking, see above link on what can be done at "data" level sniffing. It essentially lets you tag a "where" condition to any sql command like "where user() = profileid".

                                   

                                  if above is not sufficient, the authorization security model is also a pluggable interface, you can write your own implementation. see Custom Authorization Validator · GitBook 

                                  • 14. Re: OAuth with KeyCloak
                                    Christoph John Newbie

                                    Hello Ramesh,

                                    thanks for the clarification. Yes, the basic auth is correctly overwritten. I played with the Data Roles in Teiid Designer and got them working. However,  I still could not manage the row-based security stuff in teiid designer. From the Teiid docu it seems that I should be able to do what I want to do, as I can include whatever sql statement I like into the vdb. Unfortunately, the documentation lacks some examples on how to do this correctly. I could not make a significant process yet.

                                     

                                    I added a simple row constraint in teiid designer to filter based on an uuid of the registered user

                                     

                                    my_nutri_diary.Account.uuidUser = LEFT(user(), 36)

                                     

                                    Note: Teiid seems to add the security to the output of the user() function, hence I have to trim the string here. From the wildfly log the return value of the user function is 61123574-7525-463b-9d20-523133a06b94@teiid-security if I do not use the LEFT function to trim it.

                                     

                                    This gives me a correct direct comparison, if the uuid is in the same table like the one to which  the user's query is addressed.

                                     

                                    But when I have to make a join type query, I do not know how to proceed.

                                     

                                    As I stated previously, I have two tables

                                     

                                    Account: with the columns

                                    - uuid  (char 36)

                                    - ProfileID (unsigned bigint)

                                     

                                    Data, with columns

                                    - user name

                                    - user"s age

                                    - ProfileID (Foreign key of ProfileID in table Accounts)

                                     

                                    I need to find a way to add a constraint here to check "uuid" in table Account when the Data table is accessed. The teiid documentation unfortunately does not help me  here. I tried for the whole weekend to find an example in the internet, without success.

                                     

                                    So far I understand that the row constraint is added here always with a where statement at the end? I assume rather than trying with a JOIN,  I have to write some kind of CASE construct instead?

                                     

                                    So what does this mean for my requirement. if a users queries table Data with "select * from Data" he should only see his single data row and not the rows from other users. How would the constraint for this has to look like. Something like this?

                                     

                                    user() = CASE Data.ProfileID

                                                        WHEN Data.ProfileID = Account.ProfileID THEN Account.uuid

                                                 END

                                     

                                    Would be great if you could provide the right statement I have to use. Thanks for your help!

                                    1 2 Previous Next