1. Home
  2. Docs
  3. Integration of Mavryx wit...
  4. Integration of Mavryx wit...
  5. Example: Single sign-on

Example: Single sign-on

Sample implementation of Single Sign-On

Process flow diagram

Below we present a step-by-step example implementation of single sign-on.

1. Generate auhorization url

At the beginning, you need to generate a URL to the authorization endpoint. For this purpose, you need to know the client_id of the application.


            //GENERATTE STATE HERE AND SAVE
            $state = md5(time()); // Not great example ;-)

            $authenticationUri = $mavryxApiService->api()->OAuth2->getAuthorizationUrl([
                'client_id' => "c940b0ba-d81d-4739-9872-ca762b57ef69",
                'response_type' => "code",
                'state' => $state,
                'redirect_uri' => "https://someapp.co.uk/authenticate",
            ]);
            
//example authenticationUri

// https://auth.mavryx.software/oauth2/signin?client_id=c940b0ba-d81d-4739-9872-ca762b57ef69&response_type=code&state=123131234&redirect_uri=https://someapp.co.uk/authenticate

            
Parameter nameTypeRelatedDescription
client_idMavryx/Types/UuidMavryx/ClientApplication Client ID
response_typeMavryx/Types/String“code”
stateMavryx/Types/StringYour application state
redirect_uriMavryx/Types/StringWhere to redirect the user after successful login

2. Redirect user to authorization endpoint

Next, you need to redirect the user to the authorization endpoint.

return $this->redirect($authenticationUri);

3. User authenticate

If the user hasn’t previously logged into the Mavryx platform, they will see the following login screen. If the user has previously logged in, they won’t see this login screen and will be automatically redirected to the target application with the generated code token.

4. Validate response and authorization code token

After successful login, the user will be redirected to the application, and the code token will be available in the URL parameters.

// Example url https://someapp.co.uk/authenticate?code=fsadf097asf9fa7sf7sad0f0sa&state=123131234            
            
            $code = $request->get('code');
            $state = $request->get('state');

            //VALIDATE STATE AND AUTHORIZATION CODE TOKEN HERE
Parameter nameTypeRelatedDescription
codeMavryx/Types/StringAuthorization code token
stateMavryx/Types/StringYour application state

5. Exchange code token to access token

Then, you can exchange the authorization code token for an access token. Remember that you have a limited time to perform this exchange (default: 120 seconds).

If the authorization is successful, you should receive an access token and a refresh token in the response.

The access token and refresh token are 100% compliant with JWT. Therefore, you can use any JWT-compliant library for token manipulation and validation. Ex. https://web-token.spomky-labs.com

# POST:                    

# client_id  = "APP_CLIENT_ID",
# client_secret = "APP_SECRET",
# grant_type = 'authorization_code',
# code = "CODE"
                    
# https://auth-dev.mavryx.solutions/oauth2/token


            $response = $mavryxApiService->api()->OAuth2->authorize([
                    'client_id' => "c940b0ba-d81d-4739-9872-ca762b57ef69",
                    'client_secret' => "APP_SECRET",
                    'grant_type' => 'authorization_code',
                    'code' => $code,
            ]);

            $accessToken = $response->getAccessToken();
            $refreshToken = $response->getRefreshToken();
            
            if($accessToken && $refreshToken && $accessToken->isValid() && $refreshToken->isValid())
            {
            
            } else die();
            
            

Request parameters

Parameter nameTypeRelatedDescription
client_idMavryx/Types/UuidMavryx/ClientApplication Client ID
client_secretMavryx/Types/StringYour application secret
grant_typeMavryx/Types/String“authorization_code”
codeMavryx/Types/StringMavryx/CodeTokenAuthorization code token

Response objects

Parameter nameTypeRelatedDescription
access_tokenMavryx/Types/StringMavryx/AccesTokenAccess token
refresh_tokenMavryx/Types/StringMavryx/RefreshTokenRefresh token

6. Save token and retrieve user from database

At this stage, you can save the access token and refresh token in a secure location, such as sessions. Additionally, you can automatically log in the user to the application.

        $mavryxUser = $mavryxApiService->api()->OAuth2->setToken($userToken)->user()->me()()->item();
        $email = $mavryxUser->client_id;
        
        $user = $entityManager->getRepository(User::class)->findOneBy(['email' => $email]);

        return $guardHandler->authenticateUserAndHandleSuccess(
            $user,
            $request,
            $authenticator,
            'main' // firewall name in security.yaml
        );

Code example:

<?php

namespace App\Controller;

use App\Entity\User;

use App\Manager\UserPasswordManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\HttpFoundation\JsonResponse;


use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use App\Security\Oauth2Authenticator;
use Symfony\Component\Security\Http\Event\LogoutEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;


use Mavryx\Bundle\Service\MavryxApiService;



class SecurityController extends AbstractController
{

    
    /**
     * @Route("/authenticate", name="app_authenticate")
     */
    public function authenticate(AuthenticationUtils $authenticationUtils,Request $request,MavryxApiService $mavryxApiService): Response
    {
        
        $userToken = $request->cookies->get('US');
        
        if(!$userToken)
        {
            $code = $request->get('code');
            $state = $request->get('state');

            //VALIDATE STATE HERE


            $settings = $this->getParameter("mavryx");
            

            $response = $mavryxApiService->api()->OAuth2->authorize([
                    'client_id' => $settings['credentials']['client_id'],
                    'client_secret' => $settings['credentials']['client_secret'],
                    'grant_type' => 'authorization_code',
                    'code' => $code,
            ]);

            $userToken = $response->getAccessToken();

            

            $response = new RedirectResponse("/");

            $cookie = NULL;
            
            if($userToken && $userToken->isValid())
            {
                $cookie = new Cookie(
                              "US",                      // Cookie name
                              $userToken->toString(),                                       // Cookie content
                              $userToken->getExpresIn(), // Expiration date
                              "/",                                     // Path
                             "your_app_domain.com",                             // Domain
                              $request->getScheme() === 'https',       // Secure
                              false,                                   // HttpOnly
                              true,                                    // Raw
                             // 'Strict'                                 // SameSite policy
                          );
            } else {
                 $cookie = new Cookie(
                    "US",                      // Cookie name
                    "",                                       // Cookie content
                    time()-1000, // Expiration date
                    "/",                                     // Path
                    "your_app_domain.com",                             // Domain
                    $request->getScheme() === 'https',       // Secure
                    false,                                   // HttpOnly
                    true,                                    // Raw
                   // 'Strict'                                 // SameSite policy
                );
            }

            $response->headers->setCookie($cookie);
            $response->setTargetUrl('/');
            return $response;
        } else {
            
             $cookie = new Cookie(
            "US",                      // Cookie name
            "",                                       // Cookie content
            time()-1000, // Expiration date
            "/",                                     // Path
            "your_app_domain.com",                             // Domain
            $request->getScheme() === 'https',       // Secure
            false,                                   // HttpOnly
            true,                                    // Raw
           // 'Strict'                                 // SameSite policy
        );
             
            $response = new RedirectResponse("/");
             $response->headers->setCookie($cookie);
            return $response;
        }
    }
    
    
    /**
    * @Route("/logout", name="authentication_logout")
    */
    public function logoutAction(Request $request,
        EventDispatcherInterface $eventDispatcher,
        TokenStorageInterface $tokenStorage)
    {
        
        $logoutEvent = new LogoutEvent($request, $tokenStorage->getToken());
        $eventDispatcher->dispatch($logoutEvent);
        $tokenStorage->setToken(null);
        
        $cookie = new Cookie(
            "US",                      // Cookie name
            "",                                       // Cookie content
            time()-1000, // Expiration date
            "/",                                     // Path
            "your_app_domain.com",                             // Domain
            $request->getScheme() === 'https',       // Secure
            false,                                   // HttpOnly
            true,                                    // Raw
           // 'Strict'                                 // SameSite policy
        );
          
        $response = new RedirectResponse("/");
        $response->headers->setCookie($cookie);
        $response->setTargetUrl('https://auth-dev.mavryx.software/oauth2/signout');
        return $response;
    }
        
    /**
     * @Route("/login", name="app_login")
     */
    public function login(AuthenticationUtils $authenticationUtils,Request $request,EntityManagerInterface $entityManager,GuardAuthenticatorHandler $guardHandler,Oauth2Authenticator $authenticator, MavryxApiService $mavryxApiService): Response
    {
        $userToken = $request->cookies->get('US');
        
        if(!$userToken)
        {
            $settings = $this->getParameter("mavryx");

            //GENERATTE STATE HERE AND SAVE
            $state = md5(time());

            $authenticationUri = $mavryxApiService->api()->OAuth2->getAuthorizationUrl([
                'client_id' => $settings['credentials']['client_id'],
                'response_type' => $settings['credentials']['response_type'],
                'state' => $state,
                'redirect_uri' => $settings['credentials']['redirect_uri'],
            ]);
            
            return $this->redirect($authenticationUri);
        }
        
        
        $user = $mavryxApiService->api()->OAuth2->setToken($userToken)->user()->me()()->item();
        $email = $user->client_id;
        
        $user = $entityManager->getRepository(User::class)->findOneBy(['email' => $email]);

        return $guardHandler->authenticateUserAndHandleSuccess(
            $user,
            $request,
            $authenticator,
            'main' // firewall name in security.yaml
        );

    }
}
Was this article helpful to you? No Yes

How can we help?