Ferrum is a better Authorization Server, this is a Community version.
- Discord channel : https://discord.gg/9RYNYu2Mxq
Ferrum
is OpenId-Connect
Authorization server written on GO. It has Data Contract similar to
Keycloak
server (minimal Keycloak
and we'll grow to full-fledged KeyCloak
analog).
Today we are having following features:
- Issue new tokens.
- Refresh tokens.
- Control user sessions (token expiration).
- Get UserInfo.
- Token Introspect.
- Managed from external code (
Start
andStop
) making them an ideal candidate for using in integration tests for WEB API services that usesKeycloak
as authorization server; - Ability to use different data storage:
FILE
data storage for small Read only systemsREDIS
data storage for systems with large number of users and small response time;
- Ability to use any user data and attributes (any valid JSON but with some requirements), if you have to
properly configure your users just add what user have to
data.json
or in memory - Ability to become high performance enterprise level Authorization server.
it has endpoints
SIMILAR to Keycloak
, at present time we are having following:
- Issue and Refresh tokens:
POST ~/auth/realms/{realm}/protocol/openid-connect/token
- Get UserInfo
GET ~/auth/realms/{realm}/protocol/openid-connect/userinfo
- Introspect tokens
POST ~/auth/realms/{realm}/protocol/openid-connect/token/introspect
First of all build is simple run go build
from application root directory. Additionally it is possible
to generate self signed certificates - run go generate
from command line
If you don't specify the name of executable (by passing -o {execName} to go build) than name of executable = name of project
Run is simple (Ferrum
starts with default config - config.json
):
./Ferrum
To run Ferrum
with selected config i.e. config_w_redis.json
:
./Ferrum --config ./config_w_redis.json
It is possible to start app in docker with already installed REDIS
and with initial data (see python
data insert script):
docker-compose up --build
3.4 Run with direct configuration && data pass from code (embedding Authorization server in you applications)
There are 2 ways to use Ferrum
:
- Start with config file (described above)
- Start with direct pass
config.AppConfig
anddata.ServerData
in application, i.e.app := CreateAppWithData(appConfig, &testServerData, testKey) res, err := app.Init() assert.True(t, res) assert.Nil(t, err) res, err = app.Start() assert.True(t, res) assert.Nil(t, err) // do what you should ... app.Stop()
At present moment we have 2 fully integration tests, and number of them continues to grow. To run test execute from cmd:
go test
For running Manager tests on Redis
you must have redis on 127.0.0.1:6379
with ferrum_db
/ FeRRuM000
auth
user password
pair, it is possible to start docker_compose and test on compose ferrum_db
container
Configuration splitted onto several sections:
```json
"server": {
"schema": "https",
"address": "localhost",
"port": 8182,
"security": {
"key_file": "./certs/server.key",
"certificate_file": "./certs/server.crt"
}
}
```
- data file: `realms`, `clients` and `users` application takes from this data file and stores in
app memory, data file name - `data.json`
- key file that is using for `JWT` tokens generation (`access_token` && `refresh_token`),
name `keyfile` (without extensions).
Users does not have any specific structure, you could add whatever you want, but for compatibility with keycloak and for ability to check password minimal user looks like:
{
"info": {
"sub": "" // <-- THIS PROPERTY USED AS ID, PROBABLY WE SHOULD CHANGE THIS TO ID
"preferred_username": "admin", // <-- THIS IS REQUIRED
...
},
"credentials": {
"password": "1s2d3f4g90xs" // <-- TODAY WE STORE PASSWORDS AS OPENED
}
}
in this minimal user example you could expand info
structure as you want, credentials
is a service structure,
there are NO SENSES in modifying it.
Minimal full example of how to use coud be found in application_test.go
, here is a minimal snippet:
var testKey = []byte("qwerty1234567890")
var testServerData = data.ServerData{
Realms: []data.Realm{
{Name: "testrealm1", TokenExpiration: 10, RefreshTokenExpiration: 5,
Clients: []data.Client{
{Name: "testclient1", Type: data.Confidential, Auth: data.Authentication{Type: data.ClientIdAndSecrets,
Value: "fb6Z4RsOadVycQoeQiN57xpu8w8wplYz"}},
}, Users: []interface{}{
map[string]interface{}{"info": map[string]interface{}{"sub": "667ff6a7-3f6b-449b-a217-6fc5d9ac0723",
"name": "vano", "preferred_username": "vano",
"given_name": "vano ivanov", "family_name": "ivanov", "email_verified": true},
"credentials": map[string]interface{}{"password": "1234567890"}},
}},
},
}
var httpsAppConfig = config.AppConfig{ServerCfg: config.ServerConfig{Schema: config.HTTPS, Address: "127.0.0.1", Port: 8672,
Security: config.SecurityConfig{KeyFile: "./certs/server.key", CertificateFile: "./certs/server.crt"}}}
app := CreateAppWithData(appConfig, &testServerData, testKey)
res, err := app.Init()
if err != nil {
// handle ERROR
}
res, err = app.Start()
if err != nil {
// handle ERROR
}
// do whatever you want
app.Stop()
Since version 0.9.1
it is possible to use CLI Admin
See
- Run docker compose -
docker compose up --build
- List running containers -
docker ps -a
- Attach to running container using listed hash
docker exec -it 060cfb8dd84c sh
- Run admin interface providing a valid config
ferrum-admin --config=config_docker_w_redis.json ...
, see picture