Fafnir-SSO is an SSO provider, which provides a Single Sign On functionality based on industry standards and best practices, using 3rd party providers Fafnir generates JWT's which can be used uniformly by web applications in a distributed cloud based setup.
Fafnir-SSO supports the following Authentication providers:
- Unilogin
- Economic customers
- Hazelcast (Username/Password)
- Apple
- MitID
- Microsoft Identity
Fafnir-SSO issues JWT RSA-512 tokens, which can be validated using the exposed public key. The fields populated are:
- sub: The subjects name, as provided by the Authentication provider.
- iss: The issuer, which will be fafnir-, where will be the name of the provider used.
- iat: The time the JWT was issued at.
- name: The full name, as provided by the authentication provider.
In version 2 onward, configuration happens through individual environment variables. These are (Environment variables marked with ✔️ are required if you want a specific login provider to be available):
-
E-conomic
- ECONOMIC_AST - The E-conomic Application Secret Token ✔️
- ECONOMIC_AGT - The Economic Application Grant Token ✔️
-
Facebook
- FACEBOOK_AID - The Facebook Application Id ✔️
- FACEBOOK_SECRET - The Facebook Secret ✔️
-
Google
- GOOGLE_AID - The Google Application Id ✔️
- GOOGLE_SECRET - The Google Secret ✔️
-
Microsoft Identity
As Fafnir is using OpenID Connect to authenticate, you need to check the "ID tokens" box under "Implicit grant and hybrid flows" in the Authentication menu. If this box is not checked, you will receive an error upon authentication.- MSID_AID - The Azure App Application ID ✔️
- MSID_SECRET - The Azure App Client Secret ✔️
- MSID_TENANT - The Azure App's chosen tenancy ✔️
-
LinkedIn
- LINKED_IN_AID - The LinkedIn Application Id ✔️
- LINKED_IN_SECRET - The LinkedIn Secret ✔️
-
UniLogin
- UL_AID - The UniLogin Application Id
- UL_SECRET - The UniLogin Secret ✔️
- UL_WS_USER - Your UniLogin WebService username ✔️
- UL_WS_PASS - Your UniLogin WebService password ✔️
- UL_SSO - Whether to use UniLogin in Single Sign On mode, default is false.
-
Hazelcast
- HAZELCAST_USERNAME_IS_EMAIL - Determines if usernames are stored in lowercase only, so that look ups can be performed case-insensitively, default is false.
- HAZELCAST_PASSWORD_IS_ENCRYPTED - Determines if passwords are encrypted using RSA encryption, or hashed with bcrypt, default is false.
- HAZELCAST_MAP_NAME - The name of the Hazelcast Map to use for storing user data. Default is
fafnir-users
- HAZELCAST_TCP_IP_ADDRESS - Makes Fafnir connect to hazelcast using TCP/IP instead of Multicast, to the specified address.
-
MitID
- MITID_AID - The MitID ClientID ✔️
- MITID_SECRET - The MitID Client-Secret ✔️
- MITID_AUTHORITY_URL - The URL to the MitID broker authority (for example
https://brokertest.signaturgruppen.dk/op
) ✔️
If Fafnirs test mode is enabled, the MitID provider will use the
mitid_demo
scope instead ofmitid
.
Fafnir uses thessn
scope in order to add the users name to the resulting JWT. -
Fafnir
- FAFNIR_URL - The url used to access this instance of fafnir, default is http://localhost:8080
- FAFNIR_SUCCESS - The url to redirect to after successful authentication, default is http://localhost:8080/success
- FAFNIR_FAILURE - The url to redirect to after authentication failure, default is http://localhost:8080/fail
-
Testing
- TEST_ENABLED - enables the
/test
endpoint which will always return a valid jwt for a test user.
- TEST_ENABLED - enables the
In some cases you may want to store the generated keypair (or use one you generated manually). In this case you should
mount a docker volume on /var/lib/fafnir
and add the KEYSTORE_PASS
and KEY_PASS
ENV variables.
If a keystore does not already exist, one will be automatically created at startup.
The keystore is a standard JKS keystore, the key alias is "FAFNIR".
You must provide a configuration as an ACTO_CONF Environment variable, the JSON should look like this:
{
"facebookAppId": "0",
"facebookSecret": "secret",
"googleAppId": "0",
"googleSecret": "secret",
"uniLoginAppId": "0",
"uniLoginSecret": "secret",
"uniLoginWSUsername": "username",
"uniLoginWSPassword": "password",
"successUrl": "http://localhost:8080/success",
"failureUrl": "http://localhost:8080/fail",
"myUrl": "http://localhost:8080",
"enableParameter": false,
"testMode": false,
"hazelcastUsernameIsEmail": false
}
The different fields mean:
- facebookAppId: Your facebook appid, you can find this in the facebook developer console.
- facebookSecret: Your facebook secret, you can find this in the facebook developer console.
- googleAppId: Your google appid, you can find this in the google developer console.
- googleSecret: Your google secret, you can find this in the google developer console.
- uniLoginAppId: Your unilogin appid.
- uniLoginSecret: Your unilogin secret.
- uniLoginWSUsername: Your unilogin webservice username.
- uniLoginWSPassword: Your unilogin webservice password.
- uniLoginSingleSignOn: (Default: false) Choose if unilogin should be SingleLogin (false) or SingleSignOn (true)
- successUrl: The URL to redirect to when successful - the JWT will be appended to this URL.
- failureUrl: The URL to redirect to when unsuccessful.
- myUrl: The URL for the whole app.
- enableParameter: (Default: false) How the JWT token will be appended to URL, using URL?jwtToken=JWT for true or URL#JWT for false
- testMode: If set to true, on startup the service/docker image will write a test token to the log. It also enables the /test endpoint, from which you can retrieve a test token programmatically.
- hazelcastUsernameIsEmail: If set to true, the username will be treated as case insensitive when logging in. It assumes that all usernames (emails) are stored as lowercase.
On startup the server will generate a new secure RSA private key. This private key is kept in memory, so will be
destroyed when the service shuts down (unless you've explicitly enabled persistent key storage as described above),
invalidating all existing JWT's. It will also expose the public key on the /public-key
endpoint. This key is in
X509 certificate format (aka. Base64 encoded raw data). You can use this to validate your JWT.
Your JWT is returned to the success url as a fragment, as browsers do not ordinarily send this part to the server, so the JWT will not bleed through to server access logs. This means that the browser is responsible for storing the JWT securely until it is needed for API requests.
Before running this setup, you need to build the system. To build it, you need to run:
$ .\gradlew build
For running "iam" you will need to run the iam main
After running the main you can now acces http://localhost:8082/iam/org/page/1
Running the app with Docker:
$ docker-compose up --build -d