Usually when you are developing a new feature or fixing an issue, you want to focus in your business logic. If your application delegates the authentication in some SSO system you usually mocks the response from this last one. However for integration tests, it is nice to be able to test your application against the full SSO cycle, specially if you have to use things like the SAML2 Web Profile. In order to avoid you some pain registering and configuring your application in your SSO I will show you how you can use the keycloak testsuite. This will allow you to have your little but completely functional SSO system in your development environment
Keycloak is an opensource Identity and Access Management system. It is a JBoss Community project and nowadays is under the supervision of Red Hat
As it is stated in the keycloack how to run I recommend you to build your workspace using the keycloak distribution:
git clone https://github.com/keycloak/keycloak.git cd keycloak mvn clean install -DskipTests=true [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 17:50 min
All green, great! BTW, just in case my stack looks like this:
git --version git version 2.17.1 java -version java version "1.8.0_191" mvn -version Apache Maven 3.6.0
Now lets have a look at some code. If you open the tomcat8 project you will see the TomcatSamlTest.java This class contains a lot of login-logout tests like public void testPostSimpleLoginLogout() and it works off-the-shelf:
mvn test -Dtest=TomcatSamlTest#testPostSimpleLoginLogout [INFO] Building Keycloak Tomcat 8 Integration TestSuite 4.8.0.Final-SNAPSHOT .../... [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 19.351 s
In this run there are a lot of things going on. Lets have a closer look at it:
1. The keycloak server (wildfly) starts up
14:41:01,871 INFO main [org.infinispan.factories.GlobalComponentRegistry] ISPN000128: Infinispan version: Infinispan 'Estrella Galicia' 9.3.1.Final
2. The master realm and the admin user are created. A realm manages a set of users, credentials, roles, and groups. A user belongs to and logs into a realm. Realms are isolated from one another and can only manage and authenticate the users that they control. In this test the realm configuration is taken from src/test/resources/keycloak-saml/testsaml.json
14:41:08,256 INFO main [org.keycloak.services] KC-SERVICES0050: Initializing master realm 14:41:09,831 INFO main [org.keycloak.testsuite.KeycloakServer] Created master user with credentials admin:admin 14:41:09,834 INFO main [org.keycloak.testsuite.KeycloakServer] Started Keycloak (http://localhost:8081/auth) in 9414 ms
3. An apache tomcat server is started...
Dec 19, 2018 2:41:12 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["http-nio-8082"]
... and the applications declared in the TomcatSamlTest.initTomcat() are deployed. These applications take their configuration from the src/test/resources/keycloak-saml
4. The test is executed
In SendUsername Servlet doGet() request-path: / principal=bburke In SendUsername Servlet doPost() *** logout pagesource *** request-path: /logout.jsp principal=null driver url: http://localhost:8082/sales-post/saml
5. At the end tomcat and keycloak are stopped
INFO: Stopping service Tomcat 14:41:15,193 INFO main [org.keycloak.testsuite.KeycloakServer] Stopped Keycloak
It is quite simple to customize your tests, me for instance I preferred to have in the background the keycloak server running...
mvn -f keycloak/testsuite/utils/pom.xml exec:java -Pkeycloak-server -Dimport=test-suite/src/test/resources/keycloak-saml/testsaml-with-mappers.json
... and as I need to simulate my production SSO response I need to create some SAML assertion mappings so my realm configuration looks like this.
Happy testing!
Luis