Search code examples
phpoauth-2.0samlsimplesamlphp

SimpleSAMLphp generate assertion


I'm using SimpleSAMLphp as an IdP for a bunch of applications we have, chiefly a Drupal site. I've used SQL as an authsource on the IdP and that works to authenticate users, the response returns to Drupal and the users are authenticated. All good !

However we also need to use social login (login with Twitter, Facebook etc). SimpleSAMLphp supports OAuth, I've set it up and the login works on the IdP with the social accounts, SimpleSAML creates the session and cookies but I'm not authenticated on the Drupal site.

What I need to do is complete the request by returning to Drupal and authenticating the user there, that is, to issue an assertion back to Drupal on success.

Just like in the SQL source, I've mapped the attributes in each of the source files (Twitter.php, Facebook.php etc) however where SQL auth returns to Drupal and creates a session, the others just display their attributes in a template.

How do I generate and send back an assertion for Drupal from these social logins so as to authenticate my users there ?

saml10-sp-remote.php (IdP)

$metadata['https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/metadata.php/sp'] = array (
  'SingleLogoutService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
      'Location' => 'https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/saml2-logout.php/sp',
    ),
    1 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP',
      'Location' => 'https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/saml2-logout.php/sp',
    ),
  ),
  'AssertionConsumerService' =>
  array (
    0 =>
    array (
      'index' => 0,
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
      'Location' => 'https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/saml2-acs.php/sp',
    ),
    1 =>
    array (
      'index' => 1,
      'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post',
      'Location' => 'https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/saml1-acs.php/sp',
    ),
    2 =>
    array (
      'index' => 2,
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
      'Location' => 'https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/saml2-acs.php/sp',
    ),
    3 =>
    array (
      'index' => 3,
      'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01',
      'Location' => 'https://durpal_url/simplesaml_drupal_sp/module.php/saml/sp/saml1-acs.php/sp/artifact',
    ),
  ),
  'certData' => 'xxxx',
);

authsources.php (IdP)

'sql' => array(
        'sqlauth:SQL',
        'dsn' => 'mysql:host=localhost;dbname=db',
        'username' => 'user',
        'password' => 'pass',
        'query' => 'SELECT u.uid, u.name, u.mail, r.name AS role FROM users u JOIN users_roles ur on ur.uid = u.uid JOIN role r on r.rid = ur.rid where u.mail = :username AND pass = MD5(:password);',
    ),

'facebook' => array(
    'authfacebook:Facebook',
    'api_key' => 'xxxx',
    'secret' => 'xxxx',
    'req_perms' => 'email',
),

'linkedin' => array(
    'authlinkedin:LinkedIn',
    'key' => 'xxxx',
    'secret' => 'xxxx',
),

'twitter' => array(
    'authtwitter:Twitter',
    'key' => 'xxxx',
    'secret' => 'xxxx',
    'force_login' => true,
),

saml20-idp-remote.php (SP, Drupal)

$metadata['http://idp_url/simplesaml/saml2/idp/metadata.php'] = array (
  'metadata-set' => 'saml20-idp-remote',
  'entityid' => 'http://idp_url/simplesaml/saml2/idp/metadata.php',
  'SingleSignOnService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
      'Location' => 'http://idp_url/simplesaml/saml2/idp/SSOService.php',
    ),
  ),
  'SingleLogoutService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
      'Location' => 'http://idp_url/simplesaml/saml2/idp/SingleLogoutService.php',
    ),
  ),
  'certData' => 'xxx',
  'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
);

saml20-idp-hosted.php (IdP)

$metadata['__DYNAMIC:1__'] = array(
    'host' => '__DEFAULT__',
    'privatekey' => 'mysite.com.key',
    'certificate' => 'mysite.com.crt',
    'auth' => 'sql',
);

Solution

  • Background

    Your issue is that your Identity Provider is configured to use sql auth and not twitter, linkedin, etc. The drupal site will send you to the IDP and the IDP is only knowledgable about sql. While you do have authsources configured for social, SSP lets you test and verify those independently of your IDP configuration. This is why SSP is just display the social attributes in a template, and not letting you log into drupal with them.

    Option A

    multiauth will let you define an authsource that includes your social and sql. You then configure your idp to use the new multiauth authsource

    Option B

    An IDP per social provider. We run an IDP per social provider. We have multiple IDPs (with unique entityIDs) define in saml20-idp-hosted.php - one for each social account. We do it this way because each of our SPs only wants to trust a subset of all configured social IDPs.

    Each SP in this option would include the additional IDP data in saml20-idp-remote.php

    Option C

    Outsource. We run this sort of social to saml gateway as a SaaS product. This makes sense if you don't like running things yourself, or if you have a several SPs that all want different social providers, or to use different social api keys/secrets per SP.