Skip to content

Commit e8c8cfe

Browse files
authored
Merge pull request #36 from fhict-skilltree/feature/35-saml
Install SAML package and configure the basics for local development
2 parents fe17992 + 9c681dd commit e8c8cfe

26 files changed

+1045
-212
lines changed

.env.local

+4
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,7 @@ AWS_BUCKET=
4444
AWS_USE_PATH_STYLE_ENDPOINT=false
4545

4646
VITE_APP_NAME="${APP_NAME}"
47+
48+
# SAML
49+
SAML2_SP_CERT_X509=MIIDazCCAlOgAwIBAgIUK/oTTlFW/C7Vm2C6sdjWA7+HDc4wDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCbmwxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzEyMDQxOTE4MDFaFw0zMzEyMDExOTE4MDFaMEUxCzAJBgNVBAYTAm5sMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvF7zYCAbE5eEzTfkq8JBkadro0y/0kCWx0FYSekN3Aw38kYC6nxWpaawscJF3cz4Pd3zg0jgT34XeO6r3VECM6CshRmkA9fmCM6xD4jI+5dU0fR7PK8/ndnImRFpJodSYKHyb1Nb4plz6lTrTclkkJpYmrI2nlxqke7gmv1axX/3y3DXmS3QUj3aP5++SGIVwdvivXd+fWGvdNcNwbm9laUC5IGGA5CC5SpLlVo0pXdctFjv+1q1fzmlgPkpv/SqNI4JK2WJSalqu43TAvAynUPKGPjYFAbC2hOmnE1xRdnZH24Uz6PN0JKuwSa+iD+x73XazNBE1aGpVhi7iLmgPAgMBAAGjUzBRMB0GA1UdDgQWBBSVvZjErcey8q0Th9clkQmjcSTR4zAfBgNVHSMEGDAWgBSVvZjErcey8q0Th9clkQmjcSTR4zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAIUrTLAHp8IEmOSh3SWaD+D3FA4J6RhwdZvFtk3OLOqDPX4yXOy8PvcbKn7EWV3m/e1KmuGIL7GYrWhC4pMIrdcXEh8Ocv6vdrWXoOOero9rEgWZxbCsmyOJGjKlFE+rAu+12a46xtDgi+/h8n8tVwgguh5UAWtCXJqVQmkqWEk6yMCERWdv68Gi0ZtYnexKMufp8z2mdkN9AAy1OBC4Fwtb6onfXsnpTe+ogkYlOXq9dMdIu96ovNsjl0O00ctZnkPpXFEPp9HAhvpNR2I48xM/ub85jB+HaKeUnDyn/OxAa8KrxMTiTPMU4NmXObONtQb+qwEe9z3Gco3gASZCEN
50+
SAML2_SP_CERT_PRIVATEKEY=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvF7zYCAbE5eEzTfkq8JBkadro0y/0kCWx0FYSekN3Aw38kYC6nxWpaawscJF3cz4Pd3zg0jgT34XeO6r3VECM6CshRmkA9fmCM6xD4jI+5dU0fR7PK8/ndnImRFpJodSYKHyb1Nb4plz6lTrTclkkJpYmrI2nlxqke7gmv1axX/3y3DXmS3QUj3aP5++SGIVwdvivXd+fWGvdNcNwbm9laUC5IGGA5CC5SpLlVo0pXdctFjv+1q1fzmlgPkpv/SqNI4JK2WJSalqu43TAvAynUPKGPjYFAbC2hOmnE1xRdnZH24Uz6PN0JKuwSa+iD+x73XazNBE1aGpVhi7iLmgPAgMBAAECggEAAwvS6iAz8EL2N+oMIUJ1fbG8MGKehq1FwO3b/oueJ8FM0s9QSjWhOTDDHdXdGt0ybyGptN4Id+LHyDXgwFd/j+TbhEoUcCtk1kX7m0koSfHmlusOPj4zpw97qdDTFxeKR+1oZPLP+vO7Dm9sDZseV1LaUwCAu/ve7mVjeQeg5k3Bkm/qRBChxKjPh+voQG/Du9NWOAvI49JWN7KZarWWn6ZHN27oYfwdJ/xWjhsOrlcZGT0jTy8NPVsxWB8iDmlt+cDDqu745ghlcOW4acFlkElX0AVzEw3ieN7kx3aOO0i6l7aybcez3tSJLvSSk23ldwOZu8Ciq2lZsN10Ah0qvQKBgQDu8lie4kCPlSEz2fQrLF2m3Sd5RtMwtSR/uNm5Kk0vn33glA4F5cvM316lBB5k37JfuCOhZgTKEpffo5B26PiFrl7zIzMZTGoMcxGT2JGZMABNq5NINn77hv+9KM/b+27ZhrLrA8CsZ1mDLHID7ts5fmfnFFlmJWLLU+vhC4s4/QKBgQC7lsD2uJz9UbdanKXfCebEaOsmC0xJGrJVRWlovFLOZMNyMfvJf+MKxQS2XSBGjoG+CSPmZX/0ErKz45SD8+X05WJ7sGUxZNyiuByHR4+QPCxxkZ7WFT7D59UQsK7bf+yjTWLmSiAeljNLIpzlriYBNb3C3OxnzQU2zUeZ1L4o+wKBgQCa81dauTfKpJeia012jc+xfKqzb6VWabFgjfvKos7o+hGECB7L3kf59EQI2JHpMlMW1W9to52peMM6CHSPV+aJshjqrMHfPvlqV1hnusI4R7N6qq/Y3VYdQF8pSIT6j6NDtqDh3E4evuqCMNlDCarqLrmsVTrgDZBycFp/VqAS9QKBgH8oxOs536lUIE87CrFzW8veNzBVzkNr5mEpKTgHGLax1U7ulPhVSYl+XiBkZkGNzmMMfRpryV2g4yRP69e6mDH24FhqDV57OZjP5v7IwoeKUrI1fQ8v3Zkc6PBkZFOElttn1Ne4fadeN60B7ItBDqAZVuXlrhb7AkLQym17qd/LAoGAQr/pw9Z2V6gSes06c8j8cKAQDr6FkCtMjnKQnUO/JtQ2lfzQwycRNTwUTUByi6R/ynWMGel/JElcmBC4r98R2jefRMBCCBJIsDEaFmst+bgGcDd8A32wkaAAKLtRc5FKrHml7Itliv5BWpjOr82nqaD92zMWX/ddLtX3ZvYSAb4=

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
.env.production
1212
.phpunit.result.cache
1313
npm-debug.log
14+
coverage.xml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Authentication\Providers;
6+
7+
use Illuminate\Support\ServiceProvider;
8+
use Slides\Saml2\Events\SignedIn;
9+
10+
class Saml2ServiceProvider extends ServiceProvider
11+
{
12+
public function register(): void
13+
{
14+
$events = $this->app->make('events');
15+
16+
$events->listen(SignedIn::class, function (SignedIn $event) {
17+
$messageId = $event->getAuth()->getLastMessageId();
18+
19+
logger()->info('Logged in successfully');
20+
21+
// // your own code preventing reuse of a $messageId to stop replay attacks
22+
// $samlUser = $event->getSaml2User();
23+
//
24+
// $userData = [
25+
// 'id' => $samlUser->getUserId(),
26+
// 'attributes' => $samlUser->getAttributes(),
27+
// 'assertion' => $samlUser->getRawSamlAssertion()
28+
// ];
29+
//
30+
// $user = // find user by ID or attribute
31+
//
32+
// // Login a user.
33+
// Auth::login($user);
34+
});
35+
}
36+
37+
public function boot(): void
38+
{
39+
}
40+
}

app/App/Shared/Http/Kernel.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Kernel extends HttpKernel
1616
* @var array<int, class-string|string>
1717
*/
1818
protected $middleware = [
19-
// \App\Http\Middleware\TrustHosts::class,
19+
// \App\Shared\Http\Middleware\TrustHosts::class,
2020
\App\Shared\Http\Middleware\TrustProxies::class,
2121
\Illuminate\Http\Middleware\HandleCors::class,
2222
\App\Shared\Http\Middleware\PreventRequestsDuringMaintenance::class,
@@ -45,6 +45,11 @@ class Kernel extends HttpKernel
4545
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
4646
\Illuminate\Routing\Middleware\SubstituteBindings::class,
4747
],
48+
'saml' => [
49+
\App\Shared\Http\Middleware\EncryptCookies::class,
50+
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
51+
\Illuminate\Session\Middleware\StartSession::class,
52+
],
4853
];
4954

5055
/**

app/App/Shared/Providers/RouteServiceProvider.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace App\Shared\Providers;
66

77
use Illuminate\Cache\RateLimiting\Limit;
8+
use Illuminate\Config\Repository as ConfigRepository;
89
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
910
use Illuminate\Http\Request;
1011
use Illuminate\Support\Facades\RateLimiter;
@@ -30,9 +31,11 @@ public function boot(): void
3031
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
3132
});
3233

33-
$this->routes(function () {
34+
$configRepository = $this->app->get(ConfigRepository::class);
35+
36+
$this->routes(function () use ($configRepository) {
3437
Route::middleware('api')
35-
->prefix('api')
38+
->domain($configRepository->get('app.domain'))
3639
->group(base_path('routes/api.php'));
3740

3841
Route::middleware('web')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Domain\Organisation\Enums;
6+
7+
enum AuthenticationMethodType: string
8+
{
9+
case Saml2 = 'saml2';
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Domain\Organisation\Models;
6+
7+
use Domain\Organisation\Enums\AuthenticationMethodType;
8+
use Illuminate\Database\Eloquent\Factories\HasFactory;
9+
use Illuminate\Database\Eloquent\Model;
10+
11+
class AuthenticationMethod extends Model
12+
{
13+
use HasFactory;
14+
15+
/**
16+
* @var array<string>
17+
*/
18+
protected $guarded = [];
19+
20+
/**
21+
* @var array<string, string>
22+
*/
23+
protected $casts = [
24+
'type' => AuthenticationMethodType::class,
25+
'is_active' => 'boolean',
26+
];
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Domain\Organisation\Models;
6+
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Eloquent\Relations\HasMany;
10+
11+
class Organisation extends Model
12+
{
13+
use HasFactory;
14+
15+
/**
16+
* @var array<string>
17+
*/
18+
protected $guarded = [];
19+
20+
/**
21+
* @var array<string, string>
22+
*/
23+
protected $casts = [
24+
];
25+
26+
public function authenticationMethods(): HasMany
27+
{
28+
return $this->hasMany(AuthenticationMethod::class);
29+
}
30+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Domain\Skilltrees\Models;
6+
7+
use Illuminate\Database\Eloquent\Model;
8+
9+
class Skilltree extends Model
10+
{
11+
}

bootstrap/app.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
1818
);
1919

20+
// Is this really necessary?
21+
$app->useAppPath('app/App');
22+
2023
/*
2124
|--------------------------------------------------------------------------
2225
| Bind Important Interfaces

composer.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"license": "MIT",
77
"require": {
88
"php": "^8.1",
9+
"24slides/laravel-saml2": "^2.3",
910
"guzzlehttp/guzzle": "^7.2",
1011
"laravel/framework": "^10.10",
1112
"laravel/sanctum": "^3.3",
@@ -23,8 +24,8 @@
2324
},
2425
"autoload": {
2526
"psr-4": {
26-
"App\\": "app/App",
27-
"Domain\\": "app/Domain",
27+
"App\\": "app/App/",
28+
"Domain\\": "app/Domain/",
2829
"Database\\Factories\\": "database/factories/",
2930
"Database\\Seeders\\": "database/seeders/"
3031
}

0 commit comments

Comments
 (0)