Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
tutorial:adm:czechidm_installation_win [2018/11/09 14:18]
fiserp [Create CzechIdM configuration folders]
tutorial:adm:czechidm_installation_win [2019/10/17 13:26] (current)
urbanl Added changes in tomcat properties and logback spring for log rotation.
Line 1: Line 1:
 +====== Installation of CzechIdM - Windows ======
  
 +{{tag>​installation jdbc quickstart encryption}}
 +
 +We presume that the server is prepared as described in [[tutorial:​adm:​server_preparation_win|]].
 +
 +This tutorial shows how to install full production-ready version of CzechIdM on standard software setup (java, postgreSQL, Tomcat, Apache httpd). If you are looking for a demo installation please see [[:​getting-started|]].
 +
 +==== Create DB user and database in PostgreSQL ====
 +Open a **PSQL** binary from the Start menu. A windows-cmd-like window should appear with a prompt. Create a db user and a database for CzechIdM.
 +
 +<​code>​
 +CREATE USER czechidm PASSWORD '​*****';​
 +CREATE DATABASE "​czechidm"​ WITH OWNER '​czechidm'​ ENCODING '​UTF8'​ template '​template0';​
 +</​code>​
 +
 +Use the pgAdmin or PSQL to test the database connection under the ''​czechidm''​ user.
 +==== JDBC driver installation ====
 +Download the PostgreSQL JDBC driver from the [[https://​jdbc.postgresql.org/​download.html|this URL]] and move it to the C:​\CzechIdM\lib\ directory (create the directory if it does not exist).
 +==== Configure environment properties. Select application profile ====
 +Run the **Monitor Tomcat** application from the Start menu. Configure following settings:
 +  * Add ''​C:​\CzechIdM\etc;​C:​\CzechIdM\lib;​C:​\CzechIdM\lib\\*;''​ to the **beginning of the** ''​CLASSPATH''​. If you followed the [[tutorial:​adm:​server_preparation_win|]] guide, this should already be in place.
 +  * Add ''​-Dspring.profiles.active=production''​ and ''​-Djava.util.Arrays.useLegacyMergeSort=true''​to the ''​Java options''​.
 +
 +=== Change Tomat logging properties ===
 +
 +In order to set-up log rotation we need stop logging to stdout and start logging to catalina.log .
 +
 +Make these changes in file "/​c/​Program\ Files/​Apache\ Software\ Foundation/​Tomcat\ 8.5/​conf/​logging.properties"​
 +Comment out console handler. We don't want tomcat to log to stdout or stderr.
 +<​code>​
 +handlers = 1catalina.org.apache.juli.AsyncFileHandler,​ 2localhost.org.apache.juli.AsyncFileHandler,​ 3manager.org.apache.juli.AsyncFileHandler,​ 4host-manager.org.apache.juli.AsyncFileHandler
 +#handlers =  java.util.logging.ConsoleHandler
 +
 +.handlers = 1catalina.org.apache.juli.AsyncFileHandler
 +#.handlers = java.util.logging.ConsoleHandler,​
 +
 +#​java.util.logging.ConsoleHandler.level = FINE
 +#​java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
 +</​code>​
 +In 1catalina file handler change log level to "​INFO"​ and prefix from "​catalina"​ to "​tomcat"​. Also set property rotable to "​false"​. Tomcat write to this file only when starting or shutting down.
 +<​code>​
 +#​1catalina.org.apache.juli.AsyncFileHandler.level = FINE
 +#​1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
 +1catalina.org.apache.juli.AsyncFileHandler.level = INFO
 +1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/​logs
 +1catalina.org.apache.juli.AsyncFileHandler.prefix = tomcat
 +1catalina.org.apache.juli.AsyncFileHandler.rotatable = false
 +1catalina.org.apache.juli.AsyncFileHandler.suffix = .log
 +</​code>​
 +
 +
 +==== Create CzechIdM configuration folders ====
 +In CzechIdM, you can store all deployment-specific configuration (i.e. database credentials) outside the war file. This is a configure-once approach which greatly simplifies future deployments.
 +  * The **etc** directory stores configuration files.
 +  * The **lib** directory stores additional jar libraries such as database drivers.
 +  * The **backup** directory stored Groovy scripts backups.
 +  * The **data** directory stores various user-attached files.
 +
 +Create the directory structure:
 +<​code>​
 +C:\CzechIdM
 +C:​\CzechIdM\etc
 +C:​\CzechIdM\lib
 +C:​\CzechIdM\backup
 +C:​\CzechIdM\data
 +</​code>​
 +
 +==== Create SSL truststore ====
 +Open the Git Bash and navigate to the ''/​c/​czechidm/​etc''​. Then create fake certificate which will be, for this time, the only certificate in the truststore.
 +<​code>​
 +openssl genrsa -out fakecert.key
 +openssl req -new -key fakecert.key -out fakecert.csr -subj "/​C=CZ/​ST=Czech Republic/​L=Prague/​O=BCV/​CN=CzechIdM placeholder cert"
 +openssl x509 -req -in fakecert.csr -signkey fakecert.key -days 1 -sha256 -out fakecert.crt
 +keytool -importcert -file fakecert.crt -alias placeholder-cert -keystore truststore.jks
 +    Enter keystore password: ​ ENTER SOME PASSWORD HERE AND REMEMBER IT FOR LATER
 +    Re-enter new password:
 +    ...
 +    Trust this certificate?​ [no]:  yes
 +    Certificate was added to keystore
 +
 +rm fakecert.key fakecert.csr fakecert.crt
 +</​code>​
 +
 +Then adjust Tomcat configuration - the ''​JAVA_OPTS''​ - as you did before. Add path to the truststore ''​-Djavax.net.ssl.trustStore=C:/​CzechIdM/​etc/​truststore.jks''​ and truststore password ''​-Djavax.net.ssl.trustStorePassword=THE PASSWORD YOU ENTERED WHEN CREATING KEYSTORE''​.
 +
 +Save the configuration and restart the Tomcat for changes to take effect.
 +==== Create CzechIdM configuration ====
 +Now we will create configuration files the CzechIdM will use.
 +<​note>​Code snippets in this chapter can be **mostly** copy-pasted or (but please read through whole chapter to be aware of setting you have to adjust). Configuring the CzechIdM is about altering four or five lines altogether.</​note>​
 +  * The **C:​\CzechIdM\etc\secret.key** is a file with confidential storage secret key. This key has to have 128 bit (= 16 bytes). Creation of the **secret.key** is a bit tricky (because Windows). Open the Git Bash, run the **vim** editor and type the key into the file. Then check its format.<​code>​
 +cd /​c/​czechidm/​etc
 +# start the vim editor
 +vim secret.key
 +# press "​i"​ to switch to input mode
 +# type the 16 characters of the secret key
 +# press ESC to switch to command mode
 +# type :wq
 +# press ENTER
 +# now you should see that secret.key file has been created, check its contents
 +# the file should be EXACTLY 17 BYTES LONG, 16 bytes for your key and the last byte "​0a"​
 +xxd -p secret.key
 +... hex dump here ... text dump here ...
 +... 0a ...</​code>​
 +  * The **C:​\CzechIdM\etc\quartz-production.properties** file stores, the Quartz scheduler configuration. You can use the following snippet as a production-safe configuration file.<​file properties quartz-production.properties>​
 +org.quartz.scheduler.instanceName=idm-scheduler-instance
 +org.quartz.scheduler.instanceId=AUTO
 +org.quartz.scheduler.skipUpdateCheck=true
 +org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
 +org.quartz.threadPool.threadCount=10
 +org.quartz.threadPool.threadPriority=4
 +org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
 +org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
 +org.quartz.jobStore.useProperties=false
 +org.quartz.jobStore.misfireThreshold=60000
 +org.quartz.jobStore.tablePrefix=qrtz_
 +</​file>​
 +  * The **C:​\CzechIdM\etc\logback-spring.xml** specifies logging configuration. This is the default logging configuration that you can use out of the box.<​code xml logback-spring.xml>​
 +<?xml version="​1.0"​ encoding="​UTF-8"?>​
 +<!-- https://​springframework.guru/​using-logback-spring-boot/​ -->
 +<!-- http://​logback.qos.ch/​manual/​appenders.html -->
 +<​configuration>​
 +        <​springProperty name="​spring.profiles.active"​ source="​spring.profiles.active"/>​
 +        <include resource="​org/​springframework/​boot/​logging/​logback/​file-appender.xml"/>​
 +        <include resource="​org/​springframework/​boot/​logging/​logback/​defaults.xml"/>​
 +        <​springProfile name="​production">​
 +                <logger name="​eu.bcvsolutions"​ level="​INFO"/>​
 +                <logger name="​org.springframework"​ level="​INFO"/>​
 +                <logger name="​org.springframework.web"​ level="​INFO"/>​
 +                <logger name="​org.hibernate.SQL"​ level="​INFO"/>​
 +                <logger name="​org.hibernate.type.descriptor.sql.BasicBinder"​ level="​INFO"/>​
 +                <​appender name="​idm"​ class="​ch.qos.logback.core.rolling.RollingFileAppender">​
 +                        <​encoder>​
 +                                <​pattern>​
 +                                         ​%d{yyyy-MM-dd HH:​mm:​ss.SSS} %5level %relative --- [%thread] %logger{36}.%M : %msg%n
 +                                </​pattern>​
 +                        </​encoder>​
 +                        <​file>​logs/​catalina.log</​file>​
 +                        <​rollingPolicy class="​ch.qos.logback.core.rolling.TimeBasedRollingPolicy">​
 +                                <​fileNamePattern>​logs/​catalina.%d{yyyy-MM-dd}.log</​fileNamePattern>​
 +                                <​maxHistory>​90</​maxHistory>​
 +                        </​rollingPolicy>​
 +                </​appender> ​    
 +                <root level="​INFO">​
 +                        <​appender-ref ref="​idm"/>​
 +                </​root>​
 +        </​springProfile>​
 +</​configuration>​
 +</​code>​
 +  * The most important file is **C:​\CzechIdM\etc\application-production.properties** (application-PROFILE.properties,​ where the PROFILE is the profile you run the IdM under). You can use most of the file as-is, there is a bit of configuration needed though. This is a template file:<​file properties application-production.properties>​
 +# Doc: https://​wiki.czechidm.com/​devel/​dev/​configuration/​backend
 + 
 +idm.pub.app.instanceId=idm-primary
 +idm.pub.app.stage=production
 + 
 +spring.datasource.url=jdbc:​postgresql://​localhost:​5432/​czechidm
 +spring.datasource.username=czechidm
 +spring.datasource.password=********** TODO *********
 +spring.datasource.driver-class-name=org.postgresql.Driver
 +spring.datasource.validationQuery=SELECT 1
 +spring.datasource.test-on-borrow=true
 +spring.jpa.generate-ddl=false
 +spring.jpa.hibernate.ddl-auto=none
 +flyway.enabled=true
 + 
 +scheduler.enabled=true
 +scheduler.task.queue.process=1000
 +scheduler.event.queue.process=1000
 +scheduler.properties.location=quartz-production.properties
 +logging.config=c:/​czechidm/​etc/​logback-spring.xml
 +idm.sec.core.demo.data.enabled=false
 + 
 +#​spring.cache.ehcache.config=classpath:​ehcache.xml
 + 
 +spring.activiti.processDefinitionLocationPrefix=classpath*:/​eu/​bcvsolutions/​idm/​workflow/​
 +idm.sec.core.notification.template.folder=classpath*:/​eu/​bcvsolutions/​idm/​templates/​
 +idm.sec.core.script.folder=classpath*:/​eu/​bcvsolutions/​idm/​scripts/​
 +# configuration property for default backup ​
 +idm.sec.core.backups.default.folder.path=c:/​czechidm/​backup
 + 
 + 
 +idm.pub.security.allowed-origins=http://​localhost
 +# Generate JWT token security string as "cat /​dev/​urandom | tr -dc '​a-z0-9'​ | head -c VALUE" where VALUE can be from 1 to 255.
 +# We recommend the VALUE to be at least 25.
 +idm.sec.security.jwt.secret.token=********** TODO *********
 +idm.sec.security.jwt.expirationTimeout=36000000
 +
 +# recaptcha
 +# - recaptchaservice endpoint ​
 +#​idm.sec.security.recaptcha.url=https://​www.google.com/​recaptcha/​api/​siteverify
 +# - secret key, can be generated here https://​www.google.com/​recaptcha/​admin
 +idm.sec.security.recaptcha.secretKey=xxx
 +# Proxy for HTTP requests
 +#​idm.sec.core.http.proxy=12.34.56.78:​1234
 + 
 +# Cipher secret key for crypt values in confidential storage
 +# for crypt values is used secretKey or secretKey defined by file - secretKeyPath
 +#​cipher.crypt.secret.key=XXXXXXXXXXXXXXXX
 +cipher.crypt.secret.keyPath=c:/​czechidm/​etc/​secret.key
 + 
 + 
 +idm.sec.core.emailer.test.enabled=true
 +# http://​camel.apache.org/​mail.html
 +idm.sec.core.emailer.protocol=smtp
 +idm.sec.core.emailer.host=something.tld
 +idm.sec.core.emailer.port=25
 +# idm.sec.core.emailer.username=czechidm@domain.tld
 +# idm.sec.core.emailer.password=password
 +idm.sec.core.emailer.from=czechidm@localhost
 + 
 +## Global property that allow disable or enable sending notification from WF
 +idm.sec.core.wf.notification.send=false
 + 
 + 
 +# supports delete identity
 +idm.pub.core.identity.delete=true
 +#
 +# default password change type for custom users, one of values: ​
 +# DISABLED - password change is disable
 +# ALL_ONLY - users can change passwords only for all accounts
 +# CUSTOM - users can choose for which accounts change password
 +idm.pub.core.identity.passwordChange=ALL_ONLY
 +#
 +# required old password for change password
 +idm.pub.core.identity.passwordChange.requireOldPassword=true
 +#
 +# create default identity'​s contract, when identity is created
 +idm.pub.core.identity.create.defaultContract.enabled=true
 + 
 + 
 +# Default user role will be added automatically,​ after an identity is logged in
 +# could contains default authorities and authority policies configuration
 +# for adding autocomplete or all record read permission etc.
 +idm.sec.core.role.default=userRole
 +# Admin user role
 +idm.sec.core.role.admin=superAdminRole
 + 
 + 
 +# ID system against which to authenticate
 +idm.sec.security.auth.systemId=
 +
 +# attachments will be stored under this path.
 +# new directories for attachment will be created in this folder (permissions has to be added)
 +# System.getProperty("​user.home"​)/​idm_data will be used if no path is given
 +idm.sec.core.attachment.storagePath=c:/​czechidm/​data
 +</​file>​
 +
 +=== Adjust database configuration ===
 +If you followed this howto, the only thing you should need to adjust is a **spring.datasource.password** propetry. Set it to the password for czechidm user in PostgreSQL.
 +If necessary, adjust other database connection properties... <code properties>​
 +spring.datasource.url=jdbc:​postgresql://​localhost:​5432/​czechidm
 +spring.datasource.username=czechidm
 +spring.datasource.password=********** TODO *********
 +spring.datasource.driver-class-name=org.postgresql.Driver
 +spring.datasource.validationQuery=SELECT 1
 +spring.datasource.test-on-borrow=true
 +</​code>​
 +
 +=== Generate JWT token ===
 +Set value of the **idm.sec.security.jwt.secret.token** property as is described in the template file:<​code properties>​
 +# Generate JWT token security string as "cat /​dev/​urandom | tr -dc '​a-z0-9'​ | head -c VALUE" where VALUE can be from 1 to 255.
 +# We recommend the VALUE to be at least 25.
 +idm.sec.security.jwt.secret.token=********** TODO *********
 +</​code>​
 +
 +=== Local confidential storage ===
 +
 +Local confidential storage is encrypted by AES algoritm. [[https://​docs.oracle.com/​javase/​7/​docs/​api/​javax/​crypto/​Cipher.html|Read more]]. ​
 +Confidential storage is encrypted by a key found in **secret.key** file you already created.
 +
 +There are two properties in application-production.properties that influence the confidential storage:
 +  * You can set the 128bit (16byte) key directly in the property file using **cipher.crypt.secret.key** property or
 +  * you can create separate file (in our case **secret.key**) containing a random string. Then you reference this file with **cipher.crypt.secret.keyPath** property.
 +<note warning>​On Windows, you have to use separate file **secret.key**.</​note>​
 +
 +<note warning>​CzechIdM doesn'​t contain any default key for crypt confidential storage. Please define it before you start using the IdM.</​note>​
 +
 +Confidential storage uses AES/​CBC/​PKCS5Padding ([[https://​docs.oracle.com/​javase/​7/​docs/​api/​javax/​crypto/​Cipher.html|more info]]) algorithm which operates with 128bit key.
 +
 +=== Attachment store ===
 +In CzechIdM, users can sometimes add attachments (say, attach *.jpeg photo to their employee card request). Those files are stored in the attachment store.
 +With the following property, you can configure, where the store is. If you used sample property file, the store is by-default located under ''​C:​\CzechIdM\data''​.
 +
 +<code properties>​
 +# attachments will be stored under this path.
 +# new directories for attachment will be created in this folder (permissions has to be added)
 +# System.getProperty("​user.home"​)/​idm_data will be used if no path is given
 +idm.sec.core.attachment.storagePath=c:/​czechidm/​data
 +</​code>​
 +
 +=== Environment ===
 +
 +If you install CzechIdM in multiple environments (typically test and production),​ you can display a label in the navigation bar which will tell the users in which environment they work. The default value "​production"​ doesn'​t display any label. Set the value to ''​test''​ to display the label marking the Test environment.
 +<code properties>​
 +# Application stage (development,​ test, production (default))
 +idm.pub.app.stage=production
 +</​code>​
 +
 +==== Deploy the CzechIdM ====
 +CzechIdM is deployed as a WAR archive.
 +  * Download the latest CzechIdM WAR archive.
 +  * Stop the Tomcat service.
 +  * Renamed it to ''​idm.war''​ and deploy it to the stopped Tomcat server (to the ''​webapps''​ folder).
 +  * Start the Tomcat container and it will deploy the CzechIdM application. CzechIdM will load its configuration from the ''​C:​\CzechIdM\etc''​ directory automatically.
 +===== Change default admin password =====
 +In the fresh CzechIdM installation,​ there is one user identity - **admin** with password **admin**. Right after you install the application,​ go to https://​yourserver.tld/​idm and change the default password.
 +
 +===== Configure IdM =====
 +
 +Follow some final configuration steps: [[tutorial:​adm:​czechidm_installation_finalize|]].