Example of oauth2 usage with client, resource-server and authorization-server
Client and resource server were developed in Spring Boot.
Keycloak was used as authorization server.
Used Docker to containerize environment.
MongoDB was used to store some data in client and PostgreSQL was used to store Keycloak data
- Session has max inactive interval set, so in case of keycloak sso expiration, session in client application expires as well It was implemented because keycloak session could have already expired and spring oauth2 did allow user to access oauth2 protected endpoints and then fail when requesting resource-server. It would need to be manually implemented to every time check if token is valid, and if not redirect user to authorization server again. I choose more elegant way (less complex code)
- In case of user sending any additional headers (in this case: Authorization header), it is cached in mongoDB before redirection and retrieved after it, as it is lost.
- Token can expire, but it is possible to refresh it. As refreshed token will be lost at the end of the request, it is being saved to mongoDB to be used for further requests. Client token refresh logic:
- Cached data (Headers and tokens) are present for 3 days in mongoDB.
- Contains basic security configuration to check if client accessing it has proper permissions (scopes)
- Used Basic configuration with one realm, one client, one user
- Disabled https requirement for test realm so client and resource server can access it
(in production environment, it would need to be enabled and it should use valid certificate)
- Keycloak test realm is imported
- Ips had to be used, as client and resource-server have to communicate with authorization server, and if container names are used then client redirection to authorization-server for user(browser) will not work, as local computer (not container) cannot decrypt what does "http://keycloak" means. At the same time, "http://localhost" (which would work for local computer) couldn't be used as well, because it would disallow connection for user and resource-server. This was done only for example purposes, in production environment those servers would have normal dns names which would be easily resolved.
- Make sure you have
Docker
anddocker-compose
installed.
Docker CE INSTALLATION
Docker Compose INSTALLATION
- Build services:
docker-compose build
- Run services:
docker-compose up
- https://172.1.1.2:8443 - Keycloak (credentials: admin/admin)
- http://172.1.1.4:8081/oauth2/test - Client oauth2 protected endpoint (credentials: test-user/test)
- http://172.1.1.4:8081/normal/test - Client not protected endpoint