yii2-saml
yii2-saml copied to clipboard
nameIdNameQualifier and nameIdSPNameQualifier are always null?
Hi,
Firstly, thank you for this Yii2 library, it looks like it'll make my life easy to implement SAML authentication once I fully understand how to use it. I feel I'm 90% there and am just missing the last 10%. I'm 100% confident that this is going to be my error in implementation.
I have my web application setup and as far as I can see authentication against Azure AD is working. I'm redirected to Azure when I hit https://example.com/saml/login and when I'm returned to my app at I can see that when the https://example.com/saml/acs was hit with a POST request the callback function contained parameters such as email address, first name, last name and display name. However, nameIdNameQualifier and nameIdSPNameQualifier are always null. Am I doing something wrong? Have I incorrectly configured yii2-saml? Or is by design? I'm not sure if its relevant but my logout action just gives me a white page of death.. I'm not sure if it's because I'm unable to provide nameIdNameQualifier and nameIdSPNameQualifier because they're null or if that's a separate issue entirely.
As a test I have also reconfiguring my application to authenticate against Google instead of Azure.. nameIdNameQualifier and nameIdSPNameQualifier were still null from within the callback function.
Any assistance gratefully received!
Cheers
Steve
config/saml.php
<?php
$settings = array (
'strict' => true,
'debug' => true,
'sp' => array (
'entityId' => 'https://example.com/',
'assertionConsumerService' => array (
'url' => 'https://example.com/saml/acs',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
),
"attributeConsumingService"=> array(
"serviceName" => "Name",
"serviceDescription" => "Description",
),
'singleLogoutService' => array (
'url' => 'https://example.com/saml/logout',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
),
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
'x509cert' => 'XXXXXX',
'privateKey' => 'XXXXXX',
),
'idp' => array (
'entityId' => 'https://sts.windows.net/85851b04-de71-45c0-b00e-31033c6e5c80/',
'singleSignOnService' => array (
'url' => 'https://login.microsoftonline.com/85851b04-de71-45c0-b00e-31033c6e5c80/saml2',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
),
'singleLogoutService' => array (
'url' => 'https://login.microsoftonline.com/85851b04-de71-45c0-b00e-31033c6e5c80/saml2',
'responseUrl' => '',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
),
'x509cert' => 'XXXXXX',
),
);
return $settings;
Dump of the param array from within the callback function when acs is hit.
param=[
'nameId' => '[email protected]'
'sessionIndex' => '_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
'nameIdNameQualifier' => null
'nameIdSPNameQualifier' => null
'attributes' => [
'http://schemas.microsoft.com/identity/claims/tenantid' => [
0 => 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
]
'http://schemas.microsoft.com/identity/claims/objectidentifier' => [
0 => 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
]
'http://schemas.microsoft.com/identity/claims/displayname' => [
0 => 'Firstname Lastname'
]
'http://schemas.microsoft.com/identity/claims/identityprovider' => [
0 => 'https://sts.windows.net/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/'
]
'http://schemas.microsoft.com/claims/authnmethodsreferences' => [
0 => 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'
1 => 'http://schemas.microsoft.com/claims/multipleauthn'
]
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname' => [
0 => 'Firstname'
]
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname' => [
0 => 'Lastname'
]
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress' => [
0 => '[email protected]'
]
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name' => [
0 => '[email protected]'
]
]
]
SamlController.php
<?php
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\ContactForm;
use yii\helpers\Url;
use yii\helpers\VarDumper;
class SamlController extends \yii\web\Controller
{
// Remove CSRF protection
public $enableCsrfValidation = false;
public function actions() {
return [
'login' => [
'class' => 'asasmoyo\yii2saml\actions\LoginAction',
],
'acs' => [
'class' => 'asasmoyo\yii2saml\actions\AcsAction',
'successCallback' => [$this, 'callback'],
'successUrl' => Yii::$app->user->returnUrl,
],
'metadata' => [
'class' => 'asasmoyo\yii2saml\actions\MetadataAction'
],
'logout' => [
'class' => 'asasmoyo\yii2saml\actions\LogoutAction',
'returnTo' => Url::to('/site'),
'parameters' => [],
'nameId' => Yii::$app->session->get('nameId'),
'sessionIndex' => Yii::$app->session->get('sessionIndex'),
'stay' => false,
'nameIdFormat' => null,
// 'nameIdNameQualifier' => Yii::$app->session->get('nameIdNameQualifier'),
// 'nameIdSPNameQualifier' => Yii::$app->session->get('nameIdSPNameQualifier'),
'logoutIdP' => false, // if you don't want to logout on idp
],
];
}
public function actionIndex()
{
return $this->render('index', [
'saml' => Yii::$app->saml,
]);
}
/**
* @param array $param has 'attributes', 'nameId' , 'sessionIndex', 'nameIdNameQualifier' and 'nameIdSPNameQualifier' from response
*/
public function callback($param) {
\Yii::debug('IsAuthenticated()=' . VarDumper::dumpAsString( Yii::$app->saml->IsAuthenticated() ));
if (Yii::$app->saml->IsAuthenticated()) {
$eventMsg = "";
$eventMsg .= "Somebody just logged in<br />";
$eventMsg .= "User : " . ((($param['nameId']) !== null) ? $param['nameId'] : "nameId not set") . "<br />";
$eventMsg .= "IP : " . Yii::$app->getRequest()->getUserIP() . "<br />";
//$response = Yii::$app->Webhooks->SendEvent($eventMsg);
\Yii::debug('param=' . VarDumper::dumpAsString($param));
\Yii::debug('getErrors=' . VarDumper::dumpAsString(Yii::$app->saml->getErrors()));
\Yii::debug('getAttributes=' . VarDumper::dumpAsString(Yii::$app->saml->getAttributes()));
Yii::$app->session->set('nameId', $param['nameId']);
Yii::$app->session->set('sessionIndex', $param['sessionIndex']);
Yii::$app->session->set('nameIdNameQualifier', $param['nameIdNameQualifier']);
Yii::$app->session->set('nameIdSPNameQualifier', $param['nameIdSPNameQualifier']);
Yii::$app->session->set('attributes', $param['attributes']);
Yii::$app->session->set('displayname', $param['attributes']['http://schemas.microsoft.com/identity/claims/displayname'][0]);
\Yii::debug('Yii::app->user->returnUrl=' . VarDumper::dumpAsString(Yii::$app->user->returnUrl));
}
}
public function actionFlush()
{
Yii::$app->session->destroy();
Yii::$app->session->setFlash('success', "Session has been flushed.");
return $this->redirect('/saml/index');
}
}
@sscotter Did you able to figure this out?
@sscotter Did you able to figure this out?
I don't believe so. It's been a while since I touched the code but I don't recall having a breakthrough. :(
I think nameIdNameQualifier
and nameIdSPNameQualifier
are retrieved from SAML Response from your IDP Provider. Can you post your SAML Response so we can see if those values are included?