Search code examples
phpazureoauth-2.0azure-active-directorysingle-sign-on

SSO Azure AD Authentication via POST using Oauth2 - PHP


I have written a code to login using Azure AD it is working fine but when I redirect it to the next page the session variable with the values gets empty I have pasted the code for reference.

$appid = "xxxxxxxxxxxx"; //(MASKING DATA FOR OBVIOUS REASONS)

$tennantid = "xxxxxxxxxxxx"; //(MASKING DATA FOR OBVIOUS REASONS)

$secret = "xxxxxxxxxxxx"; //(MASKING DATA FOR OBVIOUS REASONS)

$login_url = "https://login.microsoftonline.com/" . $tennantid . "/oauth2/v2.0/authorize";

session_start();
$_SESSION['state'] = session_id();
echo "MS OAuth2.0 Demo ";
if (isset($_SESSION['msatg'])) {
    echo "Authenticated " . $_SESSION["uname"] . "  ";
    echo 'Log Out';
} else {
    echo 'You can Log In with Microsoft';
}

if (isset($_GET['action']) && $_GET['action'] == 'login') {
    $params = array('client_id' => $appid, 'redirect_uri' => 'https://abc.xyz.com/sso/', 'response_type' => 'token', 'response_mode' => 'form_post', 'scope' => 'https://graph.microsoft.com/User.Read', 'state' => $_SESSION['state']);
    header('Location: ' . $login_url . '?' . http_build_query($params));
}
if (array_key_exists('access_token', $_POST)) {
    $_SESSION['t'] = $_POST['access_token'];
    $t = $_SESSION['t'];
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer ' . $t,
        'Content-type: application/json'
    ));
    curl_setopt($ch, CURLOPT_URL, "https://graph.microsoft.com/v1.0/me/");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $rez = json_decode(curl_exec($ch), 1);


    if (array_key_exists('error', $rez)) {
        var_dump($rez);
        die();
    } else {
        $_SESSION['msatg'] = 1;  //auth and verified
        $_SESSION['uname'] = $rez["displayName"];
        $_SESSION['id'] = $rez["id"];
    }
    curl_close($ch);
    header('Location: https://abc.xyz.com/sso/welcome.php');
}

if (isset($_GET['action']) && $_GET['action'] == 'logout') {
    unset($_SESSION['msatg']);
    header('Location: https://abc.xyz.com/sso/');
}

When it get redirected to the welcome.php page it give me an empty array of session when I var_dump $_SESSION;

I want my data of the session to get reflected on the welcome.php page

Can someone please explain what am i doing wrong?


Solution

  • Here, I used ob_start() and ob_end_flush() by Output buffering can sometimes interfere with session data.

    Code :

    <?php
    ob_start(); 
    
    session_start();
    
    $appid = "<client_id>"; 
    $tennantid = "<tenant_id>"; 
    $secret = "<client_secret>"; 
    $login_url = "https://login.microsoftonline.com/" . $tennantid . "/oauth2/v2.0/authorize";
    
    $_SESSION['state'] = session_id();
    
    if (isset($_SESSION['msatg'])) {
        echo "Authenticated " . $_SESSION["uname"] . "  ";
        echo '<a href="?action=logout">Log Out</a>';
    } else {
        echo "MS OAuth2.0 Demo ";
        echo '<a href="?action=login">Log In with Microsoft</a>';
    }
    
    if (isset($_GET['action']) && $_GET['action'] == 'login') {
        $params = array(
            'client_id' => $appid,
            'redirect_uri' => 'https://abc.xyz.com/sso/',
            'response_type' => 'token',
            'response_mode' => 'form_post',
            'scope' => 'https://graph.microsoft.com/User.Read',
            'state' => $_SESSION['state']
        );
        header('Location: ' . $login_url . '?' . http_build_query($params));
        exit();
    }
    
    if (isset($_POST['access_token'])) {
        $_SESSION['t'] = $_POST['access_token'];
        $t = $_SESSION['t'];
    
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $t,
            'Content-type: application/json'
        ));
        curl_setopt($ch, CURLOPT_URL, "https://graph.microsoft.com/v1.0/me/");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $rez = json_decode(curl_exec($ch), true);
    
        if (isset($rez['error'])) {
            var_dump($rez);
            die();
        } else {
            $_SESSION['msatg'] = 1; 
            $_SESSION['uname'] = $rez["displayName"];
            $_SESSION['id'] = $rez["id"];
        }
    
        curl_close($ch);
        header('Location: https://abc.xyz.com/sso/welcome.php');
        exit();
    }
    
    if (isset($_GET['action']) && $_GET['action'] == 'logout') {
        unset($_SESSION['msatg']);
        header('Location: https://abc.xyz.com/sso/');
        exit();
    }
    
    ob_end_flush(); 
    ?>
    

    I added the below URL to the App Redirect URL as below,

    enter image description here

    Output :

    It runs successfully as below,

    enter image description here

    I got the below output with above output URL. Then, I click on Log In with Microsoft as below,

    enter image description here

    I was logged in with my account as below,

    enter image description here

    Below is the data that I can retrieve, and this is how the sessions work in the PHP configuration.

    enter image description here