Skip to content

Commit d984d2f

Browse files
committed
L4: basic setup finished. V 0.01 -
1 parent 5c190a8 commit d984d2f

File tree

5 files changed

+167
-47
lines changed

5 files changed

+167
-47
lines changed

src/Aacotroneo/Saml2/Saml2Auth.php

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,72 @@
66
use OneLogin_Saml2_Error;
77
use OneLogin_Saml2_Utils;
88

9+
use Log;
10+
use Psr\Log\InvalidArgumentException;
11+
912
class Saml2Auth
1013
{
1114

1215
/**
1316
* @var \OneLogin_Saml2_Auth
1417
*/
1518
protected $auth;
16-
protected $uid_key;
19+
20+
protected $samlAssertion;
21+
22+
protected $redirectUrl; //not used right now. Handled in Laravel
23+
1724

1825
function __construct($config)
1926
{
20-
// session_start();
2127
$this->auth = new OneLogin_Saml2_Auth($config);
22-
// $this->uid_key = $uid_key;
23-
// $this->id_key = $config[]
2428
}
2529

30+
/**
31+
* @return bool if a valid user was fetched from the saml assertion this request.
32+
*/
2633
function isAuthenticated()
2734
{
28-
return isset($_SESSION['samlUserdata']);
29-
}
35+
$auth = $this->auth;
3036

31-
function getUserId()
32-
{
33-
$attributes = $this->getAttributes();
34-
return $attributes[$this->uid_key][0];
37+
return $auth->isAuthenticated();
3538
}
3639

37-
function getAttributes()
38-
{
39-
$attributes = $_SESSION['samlUserdata'];
40-
return $attributes;
40+
/**
41+
* The user info from the assertion
42+
* @return Saml2User
43+
*/
44+
function getSaml2User(){
45+
46+
return new Saml2User($this->auth);
4147
}
4248

43-
function getRawSamlAssertion()
49+
/**
50+
* Initiate a saml2 login flow. It will redirect! Before calling this, check if user is
51+
* authenticated (here in saml2). That would be true when the assertion was received this request.
52+
*/
53+
function login($returnTo = null)
4454
{
45-
return isset($_SESSION['SAMLAssertion']) ? $_SESSION['SAMLAssertion'] : null;
55+
$auth = $this->auth;
56+
57+
$auth->login($returnTo);
4658
}
4759

48-
function login()
60+
/**
61+
* Initiate a saml2 logout flow. It will close session on all other SSO services. You should close
62+
* local session if applicable.
63+
*/
64+
function logout()
4965
{
50-
$this->auth->login();
66+
$auth = $this->auth;
67+
68+
$auth->logout();
5169
}
5270

71+
/**
72+
* Porcess a Saml response (assertion consumer service)
73+
* @throws \Exception when errors are encountered. This sould not happen in a normal flow.
74+
*/
5375
function acs()
5476
{
5577

@@ -58,43 +80,49 @@ function acs()
5880

5981
$auth->processResponse();
6082

61-
6283
$errors = $auth->getErrors();
6384

6485
if (!empty($errors)) {
65-
print_r('<p>' . implode(', ', $errors) . '</p>');
66-
exit();
86+
Log::error("Invalid saml response", $errors);
87+
throw new \Exception("The saml assertion is not valid, please check the logs.");
6788
}
6889

6990
if (!$auth->isAuthenticated()) {
70-
echo "<p>Not authenticated</p>";
71-
exit();
91+
Log::error("Could not authenticate with the saml response. Something happened");
92+
throw new \Exception("The saml assertion is not valid, please check the logs.");
7293
}
7394

74-
$_SESSION['samlUserdata'] = $auth->getAttributes();
75-
76-
$_SESSION['SAMLAssertion'] = $_POST['SAMLResponse']; //se lo robo al saml
7795

7896
if (isset($_POST['RelayState']) && OneLogin_Saml2_Utils::getSelfURL() != $_POST['RelayState']) {
79-
$auth->redirectTo($_POST['RelayState']);
97+
$this->redirectUrl = $_POST['RelayState'];
8098
}
8199
}
82100

101+
/**
102+
* Porcess a Saml response (assertion consumer service)
103+
* @throws \Exception
104+
*/
83105
function sls()
84106
{
85107
$auth = $this->auth;
86108

87-
$auth->processSLO();
109+
$keep_local_session = true; //we don't touch session here
110+
$auth->processSLO($keep_local_session);
88111

89112
$errors = $auth->getErrors();
90113

91-
if (empty($errors)) {
92-
print_r('Sucessfully logged out');
93-
} else {
94-
print_r(implode(', ', $errors));
114+
if (!empty($errors)) {
115+
Log::error("Could not log out", $errors);
116+
throw new \Exception("Could not log out");
95117
}
118+
96119
}
97120

121+
/**
122+
* Show metadata about the local sp. Use this to configure your saml2 IDP
123+
* @return mixed xml string representing metadata
124+
* @throws \InvalidArgumentException if metadata is not correctly set
125+
*/
98126
function getMetadata()
99127
{
100128
$auth = $this->auth;
@@ -105,11 +133,10 @@ function getMetadata()
105133

106134
if (empty($errors)) {
107135
return $metadata;
108-
// header('Content-Type: text/xml');
109-
// echo $metadata;
136+
110137
} else {
111138

112-
throw new OneLogin_Saml2_Error(
139+
throw new InvalidArgumentException(
113140
'Invalid SP metadata: ' . implode(', ', $errors),
114141
OneLogin_Saml2_Error::METADATA_SP_INVALID
115142
);

src/Aacotroneo/Saml2/Saml2User.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Aacotroneo\Saml2;
4+
5+
use Input;
6+
use OneLogin_Saml2_Auth;
7+
use Symfony\Component\HttpFoundation\Request;
8+
9+
/**
10+
* A simple class that represents the user that 'came' inside the saml2 assertion
11+
* Class Saml2User
12+
* @package Aacotroneo\Saml2
13+
*/
14+
class Saml2User {
15+
16+
17+
protected $auth;
18+
19+
function __construct(OneLogin_Saml2_Auth $auth)
20+
{
21+
$this->auth = $auth;
22+
}
23+
24+
/**
25+
* @return string User Id retrieved from assertion processed this request
26+
*/
27+
function getUserId()
28+
{
29+
$auth = $this->auth;
30+
31+
return $auth->getNameId();
32+
33+
}
34+
35+
/**
36+
* @return array attributes retrieved from assertion processed this request
37+
*/
38+
function getAttributes()
39+
{
40+
$auth = $this->auth;
41+
42+
return $auth->getAttributes();
43+
}
44+
45+
/**
46+
* @return string the saml assertion processed this request
47+
*/
48+
function getRawSamlAssertion()
49+
{
50+
return Input::get('SAMLResponse'); //rememeber this is only valid the request the assertion is received!!
51+
}
52+
53+
}

src/config/saml_settings.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?php
22

3+
//This is variable is an example - Just make sure that the urls in the 'idp' config are ok.
4+
$idp_host = 'http://idp_host/simplesaml';
5+
36
return $settings = array (
47
// If 'strict' is True, then the PHP Toolkit will reject unsigned
58
// or unencrypted messages if it expects them signed or encrypted
@@ -16,7 +19,7 @@
1619
// Specifies constraints on the name identifier to be used to
1720
// represent the requested subject.
1821
// Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported
19-
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
22+
'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
2023

2124
// Usually x509cert and privateKey of the SP are provided by files placed at
2225
// the certs folder. But we can also provide them with the following parameters
@@ -51,11 +54,11 @@
5154
// Identity Provider Data that we want connect with our SP
5255
'idp' => array (
5356
// Identifier of the IdP entity (must be a URI)
54-
'entityId' => 'http://localhost:8000/simplesaml/saml2/idp/metadata.php',
57+
'entityId' => $idp_host.'/saml2/idp/metadata.php',
5558
// SSO endpoint info of the IdP. (Authentication Request protocol)
5659
'singleSignOnService' => array (
5760
// URL Target of the IdP where the SP will send the Authentication Request Message
58-
'url' => 'http://localhost:8000/simplesaml/saml2/idp/SSOService.php',
61+
'url' => $idp_host.'/saml2/idp/SSOService.php',
5962
// SAML protocol binding to be used when returning the <Response>
6063
// message. Onelogin Toolkit supports for this endpoint the
6164
// HTTP-POST binding only
@@ -64,7 +67,7 @@
6467
// SLO endpoint info of the IdP.
6568
'singleLogoutService' => array (
6669
// URL Location of the IdP where the SP will send the SLO Request
67-
'url' => 'http://localhost:8000/simplesaml/saml2/idp/SingleLogoutService.php',
70+
'url' => $idp_host.'/saml2/idp/SingleLogoutService.php',
6871
// SAML protocol binding to be used when returning the <Response>
6972
// message. Onelogin Toolkit supports for this endpoint the
7073
// HTTP-Redirect binding only

src/controllers/Saml2Controller.php

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@
22

33
namespace Aacotroneo\Saml2\Controllers;
44

5+
use Auth;
6+
use Event;
57
use Saml2Auth;
68
use Controller;
79
use Response;
810

911

10-
class Saml2Controller extends Controller {
12+
class Saml2Controller extends Controller
13+
{
1114

12-
13-
public function metadata(){
15+
/**
16+
* Generate local sp metadata
17+
* @return \Illuminate\Http\Response
18+
*/
19+
public function metadata()
20+
{
1421

1522
$metadata = Saml2Auth::getMetadata();
1623
$response = Response::make($metadata, 200);
@@ -20,12 +27,36 @@ public function metadata(){
2027
return $response;
2128
}
2229

23-
public function acs(){
24-
return "acs";
30+
/**
31+
* Process an incoming saml2 assertion request.
32+
* Fires 'saml2.loginRequestReceived' event if a valid user is Found
33+
*/
34+
public function acs()
35+
{
36+
//if successful will redirect to
37+
Saml2Auth::acs();
38+
$user = Saml2Auth::getSaml2User();
39+
Event::fire('saml2.loginRequestReceived', array($user));
2540
}
2641

42+
/**
43+
* Process an incoming saml2 logout request.
44+
* Fires 'saml2.logoutRequestReceived' event if its valid.
45+
* This means the user logged out of the SSO infrastructre, you 'should' log him out locally too.
46+
*/
47+
public function sls()
48+
{
49+
Saml2Auth::sls();
50+
Event::fire('saml2.logoutRequestReceived');
51+
}
2752

28-
public function sls(){
29-
return "sls";
53+
/**
54+
* This initiats a logout request across all the SSO infrastructure.
55+
*/
56+
public function logout()
57+
{
58+
Saml2Auth::logout();
59+
//will actually end up in the sls endpoint
3060
}
61+
3162
}

src/routes.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
//Config::get('administrator::administrator.uri')
44
Route::group(array('prefix' => '/saml'), function() {
5-
//Admin Dashboard
5+
6+
Route::get('/logout', array(
7+
'as' => 'saml_logout',
8+
'uses' => 'Aacotroneo\Saml2\Controllers\Saml2Controller@logout',
9+
));
10+
11+
612
Route::get('/metadata', array(
713
'as' => 'saml_metadata',
814
'uses' => 'Aacotroneo\Saml2\Controllers\Saml2Controller@metadata',

0 commit comments

Comments
 (0)