This Single Sign-On (SSO) is 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,postgres
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.
This SSO server can authenticate user via external LDAP or Active Directory server. By default, this feature is disabled.
# Enable LDAP/AD authentication feature
# Default: false
sso.server.ldap.enabled=true
# Mode of LDAP/AD feature.
# Permitted values: ad, ldap
sso.server.ldap.mode=ad
# LDAP provider URL. Must starts with ldap: or ldaps:
sso.server.ldap.providerUrl=ldap://oasup.pnppk.ru:389
# Active Directory domain for binding user
sso.server.ldap.domain=oasup.pnppk.ru
# Referral policy for Active Directory search queries
# Permitted values: ignore, follow, throw, null
sso.server.ldap.referral=follow
# LDAP user distinguished name patterns
# Example: uid={0},ou=people
sso.server.ldap.userDnPatterns
# Search base for user searches. Only used with search filter
# Default: ""
# Example: ou=people
sso.server.ldap.searchBase
# The LDAP/AD filter used to search for users
# Example: (uid={0})
sso.server.ldap.searchFilter=(samaccountname={0})
# The attributes which will be retrieved from the directory.
# Null means all attributes
sso.server.ldap.userAttributes="userprincipalname, displayname"
To enable LDAP feature with full configuration, you can place
application-ldap.properties
file with all necessary properties
in current directory. After that, run application with ldap
profile.
In addition, the application defines a user to revoke JWT tokens
when external applications logout.
These 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
.
Main active profile: dev
.
Additional profiles: h2
OR postgres
.
Additional profiles determine which database the application will connect to: H2 in-memory database or PostgreSQL database inside Docker container.
Main active profile: prod
.
Additional profiles: N/A.
Application properties for production (application-prod.properties
)
mode already contains database connection parameters.
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.