Skip to content

Commit

Permalink
Add support for custom Name ID formats per IdP
Browse files Browse the repository at this point in the history
  • Loading branch information
breart committed Oct 23, 2020
1 parent 42be68e commit 7cdac60
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 4 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [2.0.5] - 2020-10-23

### Added
- The ability to customize Name ID Format for different Identity Providers

## [2.0.4] - 2020-10-22

### Added
Expand Down Expand Up @@ -90,7 +95,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Replaced underscores with dots in routes
- Minor refactoring, formatting

[Unreleased]: https://github.com/24Slides/laravel-saml2/compare/2.0.4...HEAD
[Unreleased]: https://github.com/24Slides/laravel-saml2/compare/2.0.5...HEAD
[2.0.5]: https://github.com/24Slides/laravel-saml2/compare/2.0.4...2.0.5
[2.0.4]: https://github.com/24Slides/laravel-saml2/compare/2.0.3...2.0.4
[2.0.3]: https://github.com/24Slides/laravel-saml2/compare/2.0.2...2.0.3
[2.0.2]: https://github.com/24Slides/laravel-saml2/compare/2.0.1...2.0.2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddNameIdFormatColumnToSaml2TenantsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('saml2_tenants', function (Blueprint $table) {
$table->string('name_id_format')->default('persistent');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('saml2_tenants', function (Blueprint $table) {
$table->dropColumn('name_id_format');
});
}
}
4 changes: 3 additions & 1 deletion src/Commands/CreateTenant.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
class CreateTenant extends \Illuminate\Console\Command
{
use RendersTenants;
use RendersTenants, ValidatesInput;

/**
* The name and signature of the console command.
Expand All @@ -25,6 +25,7 @@ class CreateTenant extends \Illuminate\Console\Command
{ --loginUrl= : IdP Sign on URL }
{ --logoutUrl= : IdP Logout URL }
{ --relayStateUrl= : Redirection URL after successful login }
{ --nameIdFormat= : Name ID Format ("persistent" by default) }
{ --x509cert= : x509 certificate (base64) }
{ --metadata= : A custom metadata }';

Expand Down Expand Up @@ -100,6 +101,7 @@ public function handle()
'idp_logout_url' => $logoutUrl,
'idp_x509_cert' => $x509cert,
'relay_state_url' => $this->option('relayStateUrl'),
'name_id_format' => $this->resolveNameIdFormat(),
'metadata' => $metadata,
]);

Expand Down
1 change: 1 addition & 0 deletions src/Commands/RendersTenants.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ protected function getTenantColumns(\Slides\Saml2\Models\Tenant $tenant)
'Login URL' => $tenant->idp_login_url,
'Logout URL' => $tenant->idp_logout_url,
'Relay State URL' => $tenant->relay_state_url,
'Name ID format' => $tenant->name_id_format,
'x509 cert' => Str::limit($tenant->idp_x509_cert, 50),
'Metadata' => $this->renderArray($tenant->metadata ?: []),
'Created' => $tenant->created_at->toDateTimeString(),
Expand Down
6 changes: 5 additions & 1 deletion src/Commands/UpdateTenant.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
class UpdateTenant extends \Illuminate\Console\Command
{
use RendersTenants;
use RendersTenants, ValidatesInput;

/**
* The name and signature of the console command.
Expand All @@ -24,6 +24,8 @@ class UpdateTenant extends \Illuminate\Console\Command
{ --entityId= : IdP Issuer URL }
{ --loginUrl= : IdP Sign on URL }
{ --logoutUrl= : IdP Logout URL }
{ --relayStateUrl= : Redirection URL after successful login }
{ --nameIdFormat= : Name ID Format ("persistent" by default) }
{ --x509cert= : x509 certificate (base64) }
{ --metadata= : A custom metadata }';

Expand Down Expand Up @@ -69,6 +71,8 @@ public function handle()
'idp_login_url' => $this->option('loginUrl'),
'idp_logout_url' => $this->option('logoutUrl'),
'idp_x509_cert' => $this->option('x509cert'),
'relay_state_url' => $this->option('relayStateUrl'),
'name_id_format' => $this->resolveNameIdFormat(),
'metadata' => ConsoleHelper::stringToArray($this->option('metadata'))
]));

Expand Down
64 changes: 64 additions & 0 deletions src/Commands/ValidatesInput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Slides\Saml2\Commands;

/**
* Trait ValidatesInput
*
* @package Slides\Saml2\Commands
*/
trait ValidatesInput
{
/**
* Resolve the nameIdFormat.
*
* @param string $option
*
* @return string|null
*/
protected function resolveNameIdFormat(string $option = 'nameIdFormat')
{
$value = $this->option($option) ?: 'persistent';

if ($this->validateNameIdFormat($value)) {
return $value;
}

$this->error('Name ID format is invalid. Supported values: ' . implode(', ', $this->supportedNameIdFormats()));

return null;
}

/**
* Validate Name ID format.
*
* @param string $format
*
* @return bool
*/
protected function validateNameIdFormat(string $format): bool
{
return in_array($format, $this->supportedNameIdFormats());
}

/**
* The list of supported Name ID formats.
*
* See https://docs.oracle.com/cd/E19316-01/820-3886/6nfcvtepi/index.html
*
* @return string[]|array
*/
protected function supportedNameIdFormats(): array
{
return [
'persistent',
'transient',
'emailAddress',
'unspecified',
'X509SubjectName',
'WindowsDomainQualifiedName',
'kerberos',
'entity'
];
}
}
2 changes: 2 additions & 0 deletions src/Models/Tenant.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* @property string $idp_logout_url
* @property string $idp_x509_cert
* @property string $relay_state_url
* @property string $name_id_format
* @property array $metadata
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
Expand Down Expand Up @@ -47,6 +48,7 @@ class Tenant extends Model
'idp_logout_url',
'idp_x509_cert',
'relay_state_url',
'name_id_format',
'metadata'
];

Expand Down
23 changes: 22 additions & 1 deletion src/OneLoginBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,28 @@ protected function configDefaultValues()
return [
'sp.entityId' => URL::route('saml.metadata', ['uuid' => $this->tenant->uuid]),
'sp.assertionConsumerService.url' => URL::route('saml.acs', ['uuid' => $this->tenant->uuid]),
'sp.singleLogoutService.url' => URL::route('saml.sls', ['uuid' => $this->tenant->uuid])
'sp.singleLogoutService.url' => URL::route('saml.sls', ['uuid' => $this->tenant->uuid]),
'sp.NameIDFormat' => $this->resolveNameIdFormatPrefix($this->tenant->name_id_format)
];
}

/**
* Resolve the Name ID Format prefix.
*
* @param string $format
*
* @return string
*/
protected function resolveNameIdFormatPrefix(string $format): string
{
switch ($format) {
case 'emailAddress':
case 'X509SubjectName':
case 'WindowsDomainQualifiedName':
case 'unspecified':
return 'urn:oasis:names:tc:SAML:1.1:nameid-format:' . $format;
default:
return 'urn:oasis:names:tc:SAML:2.0:nameid-format:'. $format;
}
}
}

0 comments on commit 7cdac60

Please sign in to comment.