This is a checklist of steps to be taken to setup the identity server (in standalone mode).
We assume that keycloak is installed under /usr/local/keycloak (so all paths will be relative to this).
Under modules/org/postgresql/main we must place:
module.xml: descriptor for the modulepostgresql-*.jar: the actual JAR for the PostgreSQL JDBC driver
The module.xml should contain something like:
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.3" name="org.postgresql">
<resources>
<resource-root path="postgresql-9.4.1208.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>To setup keycloak in standalone mode, edit standalone/configuration/standalone.xml.
A JKS (or PKCS12) keystore is needed to hold our keys, and it must contain a private-key entry named as server. Edit the corresponding XML fragment:
xmlstarlet sel \
-N x=urn:jboss:domain:9.0 \
-t -c 'x:server/x:management/x:security-realms/x:security-realm[@name="ApplicationRealm"]/x:server-identities/x:ssl/x:keystore' \
standalone/configuration/standalone.xml
An example content:
<keystore path="server.jks" relative-to="jboss.server.config.dir" keystore-password="secret" alias="server" key-password="secret"/>Add a driver pointing PostgreSQL module. Edit the XML fragment for drivers and add one <driver> fragment:
xmlstarlet sel \
-N x=urn:jboss:domain:9.0 -N d=urn:jboss:domain:datasources:5.0 \
-t -c 'x:server/x:profile/d:subsystem/d:datasources/d:drivers' \
standalone/configuration/standalone.xml
The result should be like this:
<drivers xmlns="urn:jboss:domain:datasources:5.0">
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="postgresql" module="org.postgresql">
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
</driver>
</drivers>Now, configure the datasource to use the PostgreSQL driver. Edit the corresponding XML fragment:
xmlstarlet sel \
-N x=urn:jboss:domain:9.0 -N d=urn:jboss:domain:datasources:5.0 \
-t -c 'x:server/x:profile/d:subsystem/d:datasources/d:datasource[@pool-name="KeycloakDS"]'
standalone/configuration/standalone.xml
An example content:
<datasource xmlns="urn:jboss:domain:datasources:5.0" jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
<connection-url>${env.database_url}</connection-url>
<driver>postgresql</driver>
<pool>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>${env.database_username}</user-name>
<password>${env.database_password}</password>
</security>
</datasource>Generally, we must restrict the interface where management service listens to. The main web application can listen to everything (but we can later narrow access to admin console).
Edit the XML fragment:
xmlstarlet sel \
-N x=urn:jboss:domain:9.0 \
-t -c 'x:server/x:interfaces' \
standalone/configuration/standalone.xml
An example content:
<interfaces xmlns="urn:jboss:domain:9.0">
<interface name="management">
<inet-address value="127.0.0.1"/>
</interface>
<interface name="public">
<inet-address value="0.0.0.0"/>
</interface>
</interfaces>We usually want to restrict access to admin console to some private network. This is performed by adding a servlet filter to Undertow servlet container.
Edit the corresponding XML fragment (add a filter definition under filters and a filter-ref under host):
xmlstarlet sel \
-N x=urn:jboss:domain:9.0 -N s=urn:jboss:domain:undertow:8.0 \
-t -c 'x:server/x:profile/s:subsystem'
standalone/configuration/standalone.xml
An example allowing access only to network 10.17.4.0/24:
<subsystem xmlns="urn:jboss:domain:undertow:8.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker security-realm="ApplicationRealm"/>
<filter-ref name="ipAccess"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<!-- Filter access to admin console -->
<expression-filter name="ipAccess" expression="path-prefix('/auth/admin') -> ip-access-control(acl={'10.17.4.0/24 allow'})"/>
</filters>
</subsystem>Edit themes/base/{account,admin,email,login}/theme.properties and add language code (e.g. el) under locales property.
Add translated messages for target language (here el) under themes/base/{account,admin,email,login}/messages/messages_el.properties
Do not forget a header line of # encoding: UTF-8 on each messages_XY.properties file.
Do not forget to enable internationalization under Realm Settings > Themes in the admin console.
Use ./bin/add-user-keycloak.sh to add a first (administrative) user to the system.
Edit welcome-content/index.html to provide a landing page (e.g redirect to the login page /auth/realms/demo/account for a specific realm)
Create /etc/default/keycloak to provide an enviroment file for keycloak service. The variables provided here as foo=bar can be substituted in standalone/configuration/standalone.xml as ${env.foo}.
An example woule be:
database_url=jdbc:postgresql://localhost/keycloak
database_username=keycloak
database_password=secret
Create the service unit file under /etc/systemd/system/keycloak.service:
[Unit]
Description=Keycloak Identity Server
After=syslog.target network.target
[Service]
Type=simple
EnvironmentFile=/etc/default/keycloak
User=ubuntu
Group=ubuntu
ExecStart=/usr/local/keycloak/bin/standalone.sh
TimeoutStartSec=600
TimeoutStopSec=600
[Install]
WantedBy=multi-user.targetEnable service:
sudo systemctl enable keycloak.service
See https://gist.github.com/drmalex07/3eba8b98d0ac4a1e821e8e721b3e1816