You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently (Symfony 6.3) OpenId is supported via 2 access token providers. The oidc_user_info and oidc which is sure a nice addition to the Symfony framework, thx to @vincentchalamon.
Beside the other authorization the coderesponse_type returns instead of #fragments a ?code=<code>. This allows us to authorization without the usage of JavaScript which I think is specially in case symfony/ux and twig based and php rendered application nice.
Example
I want to list step by step what I think would be good to add on top of the existing services of current OpenId featoure of Symfony 6.3.
This target is to implement a Single Sign On (SSO) login like this:
In this example I'm using keycloak via github (where I already login) and got sucessfully logged in and returns via the claim: email the custom user entity via a custom user provider.
1. OpenIdRedirectAuthController
The first thing what I think is required how we can link to the OpenId login page, create a /auth link to open id server. The /auth link need to implemented this way https://openid.net/specs/openid-connect-core-1_0.html#codeExample. It requires also to write something into the session of the user so my suggestion to handle this is that there is something like a security.main.openid_redirect_auth route:
<ahref="/open-id-login"> {# {{ path('security.main.openid_redirect_auth') }} #}
Login with OpenId
</a>
The generation of the /auth url requires some properties:
The OidcAuthRedirectController is not specific for the code based authorization it also could used in cases for id_token and token response type via #fragments for oidc and oidc_user_info but in case when work with PHP / Twig such mechanism is required.
2. OidcCodeExtractor
After sucessfull login on the OpenId Server (keycloak in my case) it redirects back to the given redirect_uri with a ?state=... and a &code=....
The code in this case is NOT the access_token but the code which we require to get the access_token. But first we need additional Code Extractor the existing ones only can extract the query but we also need to validate for security reasons also the saved state value so the Code Extractor could look like this:
<?phpnamespaceSulu\OidcCode\Security\AccessToken\Oidc;
useSymfony\Component\HttpFoundation\Request;
useSymfony\Component\Security\Http\AccessToken\AccessTokenExtractorInterface;
finalclass OidcCodeExtractor implements AccessTokenExtractorInterface
{
publicfunctionextractAccessToken(Request$request): ?string
{
// maybe add additional check so this check is only done on redirect_uri and not on other routes$parameter = $request->query->get('code');
$code = \is_string($parameter) ? $parameter : null;
if ($code === null) {
returnnull;
}
$state = $request->query->get('state');
$sessionState = $request->query->get('sessionState');
$savedState = $request->getSession()->get('_oidc_state');
if (!$state || $state !== $savedState) {
returnnull; // exception?
}
return$code;
}
}
Now we have extracted the code and can go into the next step.
In case we can use the OidcUserInfoTokenHandler in it but first we need to get the access_token for it via the from the token endpoint documented here:
Via this 3 additional things it would also be possible to use OpenId inside Symfony without any JS implementation and handling. As I'm not an expert in this topic I hope somebody can correct me if I did interpret something in the existing implementation or in the suggestion wrong.
From configuration point of view little bit more as in the user info is required:
token_handler:
oidc_code:
claim: emailbase_uri: 'http://keycloak.localhost:8080/realms/master/protocol/openid-connect/'# /auth, /token and /userinfo is used see https://github.com/symfony/symfony/issues/50433 for maybe better way to get this urisclient_id: 'symfony-app'client_secret: 'secret...'redirect_uri: 'https://127.0.0.1:8000'# https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaimsscope: openid # 'openid profile email phone'code_challenge: ~ # can be 'S256', 'plain', null# # client: oidc.client # custom http client
Here the steps which we are doing in this process:
Click "Login with Keycloak -> Create Redirect link with required parameter for /auth -> Login on Keycloak or via Identity Provider on Keycloak -> Redirect back to Symfony -> Extract Code and valid state -> Get access_token via /token Api -> Authenticate user via /userinfo Api -> Login sucessfully
What is missing?
Error handling is currently not implemented even keycloak returns errors they are not handled so not sure if that should be handled in OidcCodeExtractor or somewhere else.
Even the error is logged in the OidcCodeExtractor currently not possible to get it to twig or redirect to login page and show error via AuthenticationUtils
In case of successfull login via redirect_uri?state=...&code=... trough OidcCodeExtractor and OidcCodeHandler a redirect should happen this is maybe what make this oidc specially
Hope somebody can validate if I missed some steps and checks in case of security validation.
@bobvandevijver Thank you, I'm aware of the third party implementations did add it also above to the description, but as we already added openid access_token based authentication in Symfony Core, I think it make sense to also have openid code based authentication supported in the core.
Description
Currently (Symfony 6.3) OpenId is supported via 2 access token providers. The
oidc_user_info
andoidc
which is sure a nice addition to the Symfony framework, thx to @vincentchalamon.https://symfony.com/blog/new-in-symfony-6-3-openid-connect-token-handler
If I understand correctly both requires that the
client
mostly some kind of Single Page Application via React, NextJS and so on handles the OpenId login and then send the access_token or the token via fetch/ajax to a Symfony endpoint. Like in api-platform demo here https://github.com/api-platform/demo/pull/265/files#diff-5ab785e05cae9d615d004abfb686bd0409560dc13e748411bb19856773824fd9What I suggest is to implement additional a OpenId implementation via Authorization via
code
.https://openid.net/specs/openid-connect-core-1_0.html#codeExample
Beside the other authorization the
code
response_type
returns instead of#fragments
a?code=<code>
. This allows us to authorization without the usage of JavaScript which I think is specially in case symfony/ux and twig based and php rendered application nice.Example
I want to list step by step what I think would be good to add on top of the existing services of current OpenId featoure of Symfony 6.3.
This target is to implement a Single Sign On (SSO) login like this:
In this example I'm using keycloak via github (where I already login) and got sucessfully logged in and returns via the
claim: email
the custom user entity via a custom user provider.1. OpenIdRedirectAuthController
The first thing what I think is required how we can link to the
OpenId
login page, create a/auth
link to open id server. The/auth
link need to implemented this way https://openid.net/specs/openid-connect-core-1_0.html#codeExample. It requires also to write something into thesession
of the user so my suggestion to handle this is that there is something like asecurity.main.openid_redirect_auth
route:The generation of the
/auth
url requires some properties:http://keycloak/realms/master/protocol/openid-connect/
symfony-app
created open id client (need first be created)http://127.0.0.1:8000
code
random
need to be saved in session and checked later in Code Extractornonce
not sure about it yetopenid
true
orfalse
The
OidcAuthRedirectController
is not specific for thecode
based authorization it also could used in cases forid_token
andtoken
response type via#fragments
foroidc
andoidc_user_info
but in case when work with PHP / Twig such mechanism is required.2. OidcCodeExtractor
After sucessfull login on the OpenId Server (keycloak in my case) it redirects back to the given
redirect_uri
with a?state=...
and a&code=...
.The
code
in this case is NOT theaccess_token
but the code which we require to get theaccess_token
. But first we need additionalCode Extractor
the existing ones only can extract the query but we also need to validate for security reasons also the savedstate
value so theCode Extractor
could look like this:Now we have extracted the
code
and can go into the next step.3. The OidcCodeHandler
The OidcCodeHandler is very similar to the existing OidcUserInfoTokenHandler.
In case we can use the
OidcUserInfoTokenHandler
in it but first we need to get theaccess_token
for it via the from thetoken
endpoint documented here:https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
Via this 3 additional things it would also be possible to use OpenId inside Symfony without any JS implementation and handling. As I'm not an expert in this topic I hope somebody can correct me if I did interpret something in the existing implementation or in the suggestion wrong.
From configuration point of view little bit more as in the user info is required:
Here the steps which we are doing in this process:
Click "Login with Keycloak
->Create Redirect link with required parameter for /auth
->Login on Keycloak or via Identity Provider on Keycloak
->Redirect back to Symfony
->Extract Code and valid state
->Get access_token via /token Api
->Authenticate user via /userinfo Api
->Login sucessfully
What is missing?
OidcCodeExtractor
or somewhere else.OidcCodeExtractor
currently not possible to get it to twig or redirect to login page and show error viaAuthenticationUtils
redirect_uri?state=...&code=...
trough OidcCodeExtractor and OidcCodeHandler a redirect should happen this is maybe what make this oidc speciallyHope somebody can validate if I missed some steps and checks in case of security validation.
It is also worth mentioning @l-vo https://github.com/l-vo/sf_keycloak_example. Or mention by @bobvandevijver https://github.com/Drenso/symfony-oidc
The text was updated successfully, but these errors were encountered: