This Single Sign-On (SSO) is a server based on Spring Security. The main authentication routine happens through a standard login form. Further authentication occurs through Json Web Tokens (JWT), which are checked through a custom filter. In addition, there are a number of APIs that are accessed through Basic authentication with predefined users in the application configuration. All other components of the system are based on standard Spring Security beans with minor changes.
The server consists of two parts:
- Docker container with a database of users and configurations of external applications
- Java application of the server itself.
First, clone this repository and navigate to the project folder:
> cd ~
> git clone https://github.com/loolzaaa/sso-authentication-server.git
> cd sso-authentication-server
Build Docker image from project folder:
> docker build --tag sso-postgres --file .\Dockerfile-db .
Run Docker container in detached mode with published port 9898
and predefined container name
> docker run -dp 9898:5432 --rm --name sso-postgres sso-postgres
Note: --rm flag denotes deletion of container after stop. To prevent this behavior from being undesirable, you can create a physical or bind mount volume.
If you want to connect to the container database, you need to run the following command:
> docker exec -it sso-postgres /bin/bash -c "psql -U sso -d sso"
Note: the user (sso in example) and database name (sso in example) for connecting is specified in the application configuration.
If you want to see the logs of a running container, then you need to run the following command:
> docker logs -f sso-postgres
Note: this command shows logs in follow mode.
Run application with spring-boot-maven-plugin
and dev
profile active:
> ./mvnw spring-boot:run -D spring-boot.run.profiles=dev
OR you can package application to Uber JAR and run it:
> ./mvnw clean package -DskipTests
> cd ./target/
> java "-Dspring.profiles.active=dev" -jar ./auth-server-<version>.jar
Some properties can be defined to prevent other dependencies from changing the required values.
# Remove all session tracking attributes from servlet container
server.servlet.session.persistent=false
server.servlet.session.tracking-modes=
# Expose JMX endpoint for RFID key update
spring.jmx.enabled=true
# Application name for SSO
# Will be the main authority to access the application!
sso.server.application.name=passport
# Activate flag for RFID authentication through RFID key
# This type of authentication implies access
# through a SINGLE key, which is insecure!
# Default: false
sso.server.rfid.activate=true
# Login page URI
# Default: /login
sso.server.login-page=/login
# Refresh token URI for browser request
# Default: /trefresh
sso.server.refresh-uri=/trefresh
# SameSite parameter for token cookies
# Default: Lax
sso.server.cookie.same-site=Lax
# JWT TTL parameter
# Default: 30s for access, 10h for refresh
sso.server.jwt.access-ttl=5m
sso.server.jwt.refresh-ttl=10h
# Predefined users for Basic authentication
# Can be used to better restrict access
# between external applications
sso.server.basic.users[0].username=SERVICE
sso.server.basic.users[0].password=PASSWORD
# Enable Spring Actuator endpoints
# Default: false
sso.server.basic.actuatorEnable=true
Note: all basic users must have BasicUsersProperties.basicUserAuthority
authority for access.
In addition, the application defines a user to revoke JWT tokens when external applications logout.
This properties available under sso.server.basic.<property-name>
.
private String revokeUsername = "REVOKE_TOKEN_USER";
private String revokePassword = "REVOKE_TOKEN_USER_PASSWORD";
private String revokeAuthority = "REVOKE_TOKEN";
Actuator endpoints available (if enabled, see server configuration)
under Basic Authentication for special user.
These properties available under sso.server.basic.<property-name>
.
private String actuatorUsername = "actuator";
private String actuatorPassword = "1234";
private String actuatorAuthority = "ACTUATOR_ADMIN";
The user configuration schema can be viewed on the wiki page.
Secret key generation process described on the wiki page.
After generation, keys MUST have public.key
and private.key
names and can be placed in:
- classpath under
resources/keystore/
folder - somewhere on a local path specified by
sso.server.jwt.key-path
property
The application must be launched with one of two profiles: dev
(developer mode), prod
(production mode).
Optional profile: noop
, ssl
.
If you run application with optional profile noop
, then special password encoder will be active.
It is always match any password for JWT API request matchers.
RFID authentication description can be viewed on the wiki page.