Deploying Keycloak In Tomcat

Introduction

Note: You can download the source from github

AS per the Keycloak documentation currently server installation is supported only in Jboss Servers (AS,Wildfly and EAP), However it does not make sense for Organizations to use JBOSS servers only to host Keycloak, Verily they would be running servers other than JBOSS (Tomcat, Jetty, Glassfish etc.)

kt14

As per the documentation it must be a easy task for the other servers, let’s explore.

Setup

If you do a build of the keycloak server, and deploy the war to Tomcat

kt14

 Issue #1

You will get the following error, which definitely seems to be pom issue

kt14

After adding required dependency you may get other ClassNotFoundExceptions, and finally you may add the following dependencies in your pom file

[gist https://gist.github.com/mnadeem/194b09fdbf8df0e8f0d2 /]

 Issue #2

This time you would get the following error

kt14

The issue is that ResteasyProviderFactory does not have instance of org.jboss.resteasy.core.Dispatcher and javax.servlet.ServletContext so that it can inject to KeycloakAppication

kt14

To fix the issue here is what I have done.

kt14

Make sure the following dependency is also added in the pom file

<dependency>

    <groupId>javax.servlet</groupId>

    <artifactId>javax.servlet-api</artifactId>

    <scope>provided</scope>

    <version>3.1.0</version>

</dependency>

 Issue #3

After fixing the above issues you may get the following issue

kt14

The Tomcat Resource has to be configured properly

kt14

kt14

 For Tomcat external JNDI name starts with java:comp/env

Issue #4

This time you would get the following error

kt14

Copy the following jars to you TOMCAT_HOME/lib directory

kt14

Create setenv.bat/setenv.sh with the following content and copy it to TOMCAT_HOME/bin

CATALINA_OPTS=-Djavax.persistence.provider=org.hibernate.ejb.HibernatePersistence

Things should be working like a charm now

kt14

kt14

kt14

Two Issues on Keycloak

Issue #1 : No data for Dispather and ServletContext in ResteasyProviderFactory

Issue #2: keycloak-server.json is loaded from incorrect place, i.e, classes/META-INF

 config = Thread.currentThread().getContextClassLoader().getResource(“META-INF/keycloak-server.json”);

Refer this for TomEE setup

Advertisements

12 thoughts on “Deploying Keycloak In Tomcat

  1. Pingback: Deploying Keycloak In TomEE | Craftsman Nadeem
  2. Can you please provide it’s integration with one sample web application that can be deployed in tomcat?

  3. Hi Nadeem,
    I tried this and its working fine using Keycloak 1.1.0
    I have tried Keycloak 1.2-Final also and found one change is required in pom.xml file.
    Change required in pom.xml is :

    org.slf4j
    slf4j-simple
    runtime

    -I just add scope attribute as “runtime” which was “test” by default if we use Keycloak 1.2-Final so this dependency was not getting added in war file.

    -Thanks
    Mayank

  4. Hi Nadeem,

    I am able to deploy and run keycloak-1.1.0 in tomcat as per your instructions.

    And also able to login in ‘Master’ realm using admin/admin credentials.

    But, I am not able to create new realm (‘demo’). Its giving “Error! An unexpected server error has occurred ” error in keycloak.

    Can you please help to me, how we can resolve this thing.

    Thanking you very much in advance.

    TOMCAT – LOG :
    Jun 09, 2015 10:15:24 AM org.apache.catalina.core.ApplicationContext log
    INFO: ContextListener: contextInitialized()
    Jun 09, 2015 10:15:24 AM org.apache.catalina.core.ApplicationContext log
    INFO: SessionListener: contextInitialized()
    Jun 09, 2015 10:15:24 AM org.apache.catalina.core.ApplicationContext log
    INFO: ContextListener: attributeAdded(‘org.apache.jasper.compiler.TldLocationsCache’, ‘org.apache.jasper.compiler.TldLocationsCache@4cdb366’)
    Jun 09, 2015 10:19:44 AM org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet [Keycloak REST Interface] in context with path [/auth] threw exception
    java.lang.RuntimeException: request path: /auth/admin/realms
    at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:54)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2442)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2431)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
    Caused by: org.jboss.resteasy.spi.UnhandledException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “clientRoles” (Class org.keycloak.representations.idm.UserRepresentation), not marked as ignorable
    at [Source: java.io.StringReader@31adf6a9; line: 27, column: 29] (through reference chain: org.keycloak.representations.idm.RealmRepresentation[“users”]->org.keycloak.representations.idm.UserRepresentation[“clientRoles”])
    at org.jboss.resteasy.core.SynchronousDispatcher.handleApplicationException(SynchronousDispatcher.java:365)
    at org.jboss.resteasy.core.SynchronousDispatcher.handleException(SynchronousDispatcher.java:233)
    at org.jboss.resteasy.core.SynchronousDispatcher.handleInvokerException(SynchronousDispatcher.java:209)
    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:557)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.keycloak.services.filters.ClientConnectionFilter.doFilter(ClientConnectionFilter.java:41)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:40)
    … 18 more
    Caused by: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “clientRoles” (Class org.keycloak.representations.idm.UserRepresentation), not marked as ignorable
    at [Source: java.io.StringReader@31adf6a9; line: 27, column: 29] (through reference chain: org.keycloak.representations.idm.RealmRepresentation[“users”]->org.keycloak.representations.idm.UserRepresentation[“clientRoles”])
    at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
    at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
    at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
    at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)
    at org.codehaus.jackson.map.deser.BeanDeserializer._handleUnknown(BeanDeserializer.java:725)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:703)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:194)
    at org.codehaus.jackson.map.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
    at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1863)
    at org.keycloak.util.JsonSerialization.readValue(JsonSerialization.java:46)
    at org.keycloak.services.resources.admin.RealmsAdminResource.uploadRealm(RealmsAdminResource.java:170)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227)
    at org.jboss.resteasy.core.ResourceLocator.invokeOnTargetObject(ResourceLocator.java:159)
    at org.jboss.resteasy.core.ResourceLocator.invoke(ResourceLocator.java:92)
    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542)
    … 33 more

  5. Hi Mohammad, thanks for this tutorial. I want to ask you if you know how to edit the layout of the keycloak login form, the .htmls and .css. Do I have to install locally other projects?

  6. I deployed keycloak in tomcat with eclipse Luna based on this tutorial.

    I have it running in my machine and have no problem. Now I have to edit the login form based on my company design. But I do not have local files .css and .htmls to do it.

    Do I have to donwload the war project, the parent project? I do not know where to start.

    Thanks in advanced.

  7. Hi, I am unable to find the keycloak war, specifically the keycloak server you mentioned.
    It looks like the Keycloak Github structure might have changed a bit since you wrote this.
    Any idea where I could get the war?

    Also do you have any idea if some of the newer versions, say 1.7.0 would work with the instructions in this post?

  8. Hi!
    When the application was fired up, I got this kind of exception which is
    java.io.FileNotFoundException: C:\Program%20Files\Apache%20Software%20Foundation\Tomcat%208.0_Tomcat80\webapps\auth\WEB-INF\classes\META-INF\keycloak-server.json (The system cannot find the path specified)

    Any idea on this?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s