Migrate FOS-User to Keycloak SSO
FOS User Bundle died
FOS USer bundle is not supported any more, but worked until Symfony 4.4.11. If you want to upgrade you need to change the FOS-User Library or implment the Security by yourself.
Why Keycloak
Keycloak makes it easy to manage Users over several Applications and grant access to each of your own application.
With KEycloak you can als integrate social Login like Facebook, Goolge or Github as an Identity Provider.
How to implment
- We want to take all our User we managed with FOS and try to connect them with the new SSO Service
- We want to use the internal Symfony Security Bundle to manage local Application Users
- We want to authenticate with a guard the given firewalls
1. Remove FOS-User Bundle
First remove all Stuff from FOS-User from your composer.json.
Remove the fos_user from configuration and from the routing.
Look in the services.yaml, if there is something from the FOS-User Bundle.
Remove everything that is from FOS-User from the security.yaml
#config/packages/security.yaml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
#remove from here
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
check_path: fos_user_security_check
login_path: fos_user_security_login
logout:
path: fos_user_security_logout
remember_me:
secret: '%kernel.secret%'
lifetime: 86400 # 1 day in seconds
path: /
always_remember_me: true
#remove to here
If you don`t do so, you could get later when compose trys to clean the cache. run
composer update
to remove FOS-User-Bundle correct.
2. Install KNP-OAUTH2 Bundle and Keycloak Extension
We will use:
https://github.com/knpuniversity/oauth2-client-bundle
and
https://github.com/stevenmaguire/oauth2-keycloak
composer require knpuniversity/oauth2-client-bundle stevenmaguire/oauth2-keycloak
Hopefully this will install without error. If there are errors, please fix it by removing the FOS-User Parts.
3. Generate new Config Files
Composer will add some new config files with the reciept.
Configuration file to tell the boundle to use keycloak
#config/packages/knpu_oauth2_client.yaml
knpu_oauth2_client:
clients:
keycloak_main:
# must be "keycloak" - it activates that type!
type: keycloak
# add and set these environment variables in your .env files
client_id: '%env(OAUTH_KEYCLOAK_CLIENT_ID)%'
client_secret: '%env(OAUTH_KEYCLOAK_CLIENT_SECRET)%'
# a route name you'll create
redirect_route: connect_keycloak_check
redirect_params: {}
# Keycloak server URL
auth_server_url: '%env(OAUTH_KEYCLOAK_SERVER)%'
# Keycloak realm
realm: '%env(OAUTH_KEYCLOAK_REALM)%'
# Optional: Encryption algorith, i.e. RS256
# encryption_algorithm: null
# Optional: Encryption key path, i.e. ../key.pem
# encryption_key_path: null
# Optional: Encryption key, i.e. contents of key or certificate
# encryption_key: null
# whether to check OAuth2 "state": defaults to true
# use_state: true
New security.yaml we see what the different parts are later
#config/packages/security.yaml
security:
encoders:
App\Entity\User:
algorithm: auto
role_hierarchy:
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_ADMIN: [ROLE_ALLOWED_TO_SWITCH]
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
users:
entity:
class: App\Entity\User
property: keycloakId
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: true
switch_user: true
logout:
path: app_logout
target: logout_keycloak
guard:
authenticators:
#here we connect our guard to protect the firewall
- App\Security\GuardServiceKeycloak
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: /backend/, role: ROLE_ADMIN }
- { path: /login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /no_team$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /cron/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /client/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /register, role: ROLE_ADMIN }
- { path: /, role: ROLE_USER }
The route to logout
#config/routes.yaml
...
app_logout:
path: /login/logout
methods: GET
Set some parameters we later need in the application
#config/services.yaml
...
parameters:
KEYCLOAK_URL: '%env(OAUTH_KEYCLOAK_SERVER)%'
KEYCLOAK_REALM: '%env(OAUTH_KEYCLOAK_REALM)%'
KEYCLOAK_SECRETE: '%env(OAUTH_KEYCLOAK_CLIENT_SECRET)%'
KEYCLOAK_ID: '%env(OAUTH_KEYCLOAK_CLIENT_ID)%'
Some new Env-Variables in your .env file You need to set them in your .env.local to the correct values. These values you should get from your Admin.
Important: the URL ist the https://domain/auth
#.env
###> oauth-bundle ###
OAUTH_KEYCLOAK_CLIENT_ID=addHere
OAUTH_KEYCLOAK_CLIENT_SECRET=addHere
OAUTH_KEYCLOAK_SERVER=addHere/auth
OAUTH_KEYCLOAK_REALM=addHere
###< oauth-bundle ###