codegreencreative / laravel-samlidp Goto Github PK
View Code? Open in Web Editor NEWLaravel SAML IdP
License: MIT License
Laravel SAML IdP
License: MIT License
I've made the login from my SP work. but when the user logs out, it appears logged out on my SP. If I hit the login again, the SP login screen prompts. Good so far. but if I chose the same IdP login link again, it authenticates me right away without redirecting me to the IdP login screen. Feel that the IdP didn't actually log me out. In my IdP's .env file, I do have this line: LOGOUT_AFTER_SLO=true.
But if I close the browser after the first logged out, then visit the SP login and choose IdP login link, it redirects me to the IdP login screen. So to completely logout of the IdP, the user must close the browser otherwise it stays logged in on IdP, is this the right behavior?
If this is expected behavior, are there any ways I can force the user on the SP to enter their email/password on the IdP login screen again without closing the browser?
This parameter is provided in the default samlidp.php config file, but isn't mentioned in the docs.
Hi,
is there support for Laravel 6.0 planned?
The currently used Version:
"illuminate/support": "^5.6",
"illuminate/routing": "^5.6",
are only allowing up to laravel 5.8
Thanks
Hello
Not sure if I'm missing something or if it's attended, but after logging in via SSO i'm not redirected back to the SP initiator and instead i'm just taken to the home page of the IdP.
I'm using /login as the IdP ACS URL.
Thanks
When uploading the metadata 'as is' some service providers, like https://samltest.id will trip over the
-----BEGIN CERTIFICATE-----
and
-----END CERTIFICATE-----
lines.
I think these lines should be stripped when generating the certificates or -probably better- before putting out the metadata.xml.
The newlines may be removed from the certificate as well.
This is a promising project by the way!
I have followed all of the setup instructions for this package and that all makes sense.
My question is around the use of @samlidp. inside my login blade.
I placed it just under @csrf in my blade file but when I inspect the HTML I do not see the output I expect, which I'm assuming should be identical to: https://github.com/codegreencreative/laravel-samlidp/blob/master/resources/views/components/input.blade.php
However, nothing is rendered.
Both controllers (CodeGreenCreative\SamlIdp\Http\Controllers\LogoutController
and CodeGreenCreative\SamlIdp\Http\Controllers\MetadataController
) are extending App\Http\Controllers\Controller
. This class not necessarily exists. For example we renamed our namespace.
Instead the controllers should extend Illuminate\Routing\Controller
as it is the basic controller.
Also I don't see a reason why they are extending this controller. Maybe there was a reason that I don't see...
Hi,
I've installed and configured this library on a laravel project with Fortify as authentication backend.
I followed the readme for installation and configuration but when I open the /login url nothing happens: the default login with email/password is shown and working and in the html source there is no output for @samlidp
Can someone help me?
Thanks a lot!
Can the composer.json file be updated for the newest release of Laravel?
Thank you!
I have two SP's, when singing on, only one does, when logging out all of them does. I think it supposed to login across all SSO infrastructure
Hi there,
In our organization our users have an account in the office365, we wanted to make our SSO to sign in the users in to Office365, but we have face some problems the first one is that the office365 is routing to /login with POST
method this isn't a big deal, the problem is with the SAMLRequest
coming form mirosoft which dose not contain AssertionConsumerServiceURL
.
Normal Saml Request:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ONELOGIN_ae3a207258e0ebd73a13e8dc231b3cd44680105a"
Version="2.0"
ProviderName="Display Name"
IssueInstant="2021-08-10T07:48:41Z"
Destination="http://localhost:8030/login"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="http://localhost:8010/saml/test/acs"
>
<saml:Issuer>http://localhost:8010/saml/test/metadata</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
AllowCreate="true"
/>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
Saml Request from Microsoft:
<samlp:AuthnRequest ID="_e8039dc5-3744-4b00-b2c8-7b985dea2928"
Version="2.0"
IssueInstant="2021-08-10T11:48:45.996Z"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
>
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">urn:federation:MicrosoftOnline</Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
</samlp:AuthnRequest>
Any idea to resolve this problem.
reference: https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-fed-saml-idp
Thank You.
Issue: PerformsSingleSignOn
is always trying to get files called cert.pem
and key.pem
instead of getting the file names from samlidp config.
How to reproduce: name the certificate file anything other than cert.pem
or the certificate file key key.pem
Error:
File not found at path: cert.pem (0)
Illuminate\Contracts\Filesystem\FileNotFoundException thrown with message "cert.pem"
Issue in \CodeGreenCreative\SamlIdp\Traits\PerformsSingleSignOn::init
:
$this->certificate = (new X509Certificate)->loadPem(Storage::disk('samlidp')->get('cert.pem'));
$this->private_key = Storage::disk('samlidp')->get('key.pem');
Suggested tested solution:
$this->certificate = (new X509Certificate)->loadPem(Storage::disk('samlidp')->get(config('samlidp.certname', 'cert.pem')));
$this->private_key = Storage::disk('samlidp')->get(config('samlidp.keyname', 'key.pem'));
Should I do some workaround like sending POST request to SP's to register user or is there any option in configuration that support that ?
So, we are NOT going to modify config files, but we can provide a bit of code to copy and paste into a config file. Here's the proposed flow:
Command:
php artisan samlidp:sp`
Ask
for SP destination (ACS) URLAsk
for SP logout URLconfig/samlidp.php
Hello,
i am new to sso and I try to authorize https://sptest.iamshowcase.com.
But I always run into "Invalid PEM encoded certificate".
I created an SP with "php artisan samlidp:sp"
"
'sp' => [
'aHR0cHM6Ly9zcHRlc3QuaWFtc2hvd2Nhc2UuY29tL2Fjcw==' => [
'destination' => 'https://sptest.iamshowcase.com/acs',
'logout' => '',
//'certificate' => '',
//'query_params' => false
]
"
After that I uploaded my metadata file to sptest.iamshowcase.com.
But when I try now to login over "https://sptest.iamshowcase.com/ixs?idp=ee55f286fbd8efe77e2033ad817fd91e04de4e01"
I got every time after pushing the Login button the "Invalid PEM encoded certificate" error.
I tried it with Laravel 6 and 8 an samlidp 2 and 5
can someone help me?
At the end I will work with sli.do as SP
THX for Help
Nils
In the SSO Job the assertion dates conditions should take into account the timestamp of the request. In my Case the SP Server creates a Request with a Timestamp -3 Minutes from the IDP Timestamp.
So the IDP Response assertsion fails because the notBefore Timestamp is set to IDP Timestamp.
Maybe set the notBefore Timestamp to the request creation Time, like this:
->setConditions(
(new Conditions)
->setNotBefore($this->authn_request->getIssueInstantTimestamp())
I have a query regarding the logout route, from my service provider I hit logout and this goes to https://myapp.com/logout
but when it hits the logout route I get a 405 error as the default logout expects a POST request.
Does this mean I've set something up wrongly as this would imply that your listener is not firing.
<?php
namespace CodeGreenCreative\SamlIdp\Listeners;
use Illuminate\Auth\Events\Logout;
class SamlLogout
{
/**
* Upon logout, initiate SAML SLO process for each Service Provider
* Simply redirect to the saml/logout route to handle SLO
*
* @param Logout $event
* @return void
*/
public function handle(Logout $event)
{
// Make sure we are not in the process of SLO when handling the redirect
if (in_array($event->guard, config('samlidp.guards')) && null === session('saml.slo')) {
abort(redirect('saml/logout'), 200);
}
}
}
To me, it looks like it should just redirect to saml/logout
, however I get a 405 error.
what is the problem of supporting Laravel 7 and 8 together?
I've tried adding dds and Logs to my regular app/Http/Controllers/LoginController but the changes never are reflected, how would I achieve this? I want to check if $user->is_active
is true.
I have everything set up, however, I am strictly using laravel as an API, and I do not want to marry the login system to the Service Provider. I want to be able to generate the assertion values and send them to the service provider at a later date, but am unsure how to use this package to do that or if it is even possible.
I get an exception because Str::finish
expects a string but gets an UrlGenerator
. I haven't defined any SP on my local machine and the call url($destination)
at /src/Jobs/SamlSso.php#L167
returns the UrlGenerator
.
Of course as we don't have anything defined in config.sp.*
... Shouldn't we throw as soon as he is redirected to the login page with an invalid SP?
Versions:
codegreencreative/laravel-samlidp v2.0.5
laravel/framework v6.18.2
Is it possible to store the list of Service Provider in the database and grab it from there whenever someone login/logout ?
Or is it a security issue?
I have this use case I want to implement. I need to implement a feature to close all session for specific user as administrator. I am new to SAML implementation so I don't know if this is something that SAML support or need to be handled apart.
Do you think is something that can be done with this library ?
thanks in advance for the help or the guidence that you can give me.
I have a service provider (Twilio Flex) that needs nested attributes for certain functionality:
"routing": { "skills": [ "Spanish", "Latin" ] }
Is it possible to set nested attributes in SamlAssertionAttributes.php
?
I tried the naive way:
$skills = new Attribute('skills', ['Spanish', 'Latin']);
$event->attribute_statement
->addAttribute(new Attribute(ClaimTypes::PPID, $user->id))
->addAttribute(new Attribute('routing', $skills));
...but that didn't work.
Similar issue: #33
Issue: MetadataController
is always trying to get files called cert.pem
instead of getting the file names from samlidp config.
How to reproduce: name the certificate file anything other than cert.pem
Error:
File not found at path: cert.pem (0)
Illuminate\Contracts\Filesystem\FileNotFoundException thrown with message "cert.pem"
Issue in \CodeGreenCreative\SamlIdp\Http\Controllers\MetadataController::index
:
$cert = Storage::disk('samlidp')->get('cert.pem');
Suggested tested solution:
$cert = Storage::disk('samlidp')->get(config('samlidp.certname', 'cert.pem'));
I am trying to generate certificate using the command given and I'm getting this message
$ php artisan samlidp:cert [--days=7300 --keyname=key.pem --certname=cert.pem]
No arguments expected for "samlidp:cert" command, got "[--days=7300".
Minor issue; when a host has short_open_tag=1 -I know …very bad practice- and you cannot do anything about it (in php.ini) then calling /saml/metdata will fail because of the opening XML-tag.
As an ugly workaround, replacing the opening tag with
<?php echo '<?xml version="1.0"?>'?>
will work.
I'm not sure if this should be fixed here. As said, using short tags is a bad practice anyway.
Hey i'm using this as my laravel as idp and google as sp.
after i request to https://mail.google.com/a/domain.com it redirected to my apps. after login, it keep redirect to gmail service.
any solution to make the redirection pointed to my apps instead google service?
thanks
SimpleSaml is rather strict when comparing destinations. The idp query parameter causes an exception when testing locally.
Caused by: Exception: Destination in response doesn't match the current URL. Destination is "http://localhost/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp?idp=http://localhost", current URL is "http://localhost/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp".
Commenting the parameter out on https://github.com/codegreencreative/laravel-samlidp/blob/master/src/Jobs/SamlSso.php#L59 seems to fix it.
Hey there, question, I have the debug flag turned on, but none is being written in the .log file.
I am basically looking to get the .xml being exchanged in the requests/responses, any way better than other to do that ?
issue was fixed here: #34 on master, @upwebdesign can I ask you to please apply the fix to v2.0 also
In the SamlIdpServiceProvider
there is an issue with the Blade directive when loading the login page with a SAMLRequest. It's just not working. I found an example that may lead us in the right direction.
https://github.com/spatie/laravel-honeypot/blob/master/src/HoneypotServiceProvider.php
Hi,
Great package, and hoping to integrate it into our SSO solution. However, I'm running into a problem with single-log-off, initiated from service provider. An incoming logout request seems to cause SamlSlo.php to blow up with a class not found error -
Class 'CodeGreenCreative\SamlIdp\Jobs\DeserializationContext' not found
If I add - use LightSaml\Model\Context\DeserializationContext;
to the beginning of the file, it works.
Using Laravel 5.8.35. If you need any more detail, please let me know.
Thanks,
Kevin.
When logging out, the request is broadcasted to all SP's fine, but you remain logged in to the IDP, so when the SP returns you to log in, you're still logged in despite logging out.
This may not be a bug, but didn't feel semantically correct.
can you describe in this situation can i make that my app will be IDp and Azure AD as a SP, with your package?
Hi all. I have setup my service providers successfully. But unfortunately I can't find what is the SSO url of this library. I have added the saml directive in the login page. But how should an SP initiate going to the IDP (this lib)? That is, what is the SSO url to initiate the authentication process?
Thanks for your work.
When using multiple guards, it seems using the auth()
helper doesn't suffice as it doesn't return a user for me. (it returns null
instead).
I could solve it by passing the guard name in SamlLogin event:
if (in_array($event->guard, config('samlidp.guards')) && request()->filled('SAMLRequest') && ! request()->is('saml/logout')) {
abort(response(SamlSso::dispatchNow($event->guard)), 302);
}
And passing it to the constructor of SamlSso:
public function __construct($guard = null)
{
$this->guard = $guard;
$this->init();
}
Finally I now access the User model through the Auth
facade:
Auth::guard($this->guard)->user()
(Laravel 8.12, PHP 8.0)
Thought I'd post it here as an issue as I'm not sure this proposed change is wanted or someone recognises the issue as a possible auth configuration error. Thank you!
Hi,
I was integrating this idp with a service that requires me to have an AuthnContextClassRef, it by default accepts:
urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified
which seems pretty standard.
But in this package for some reason the default value found here
laravel-samlidp/src/Jobs/SamlSso.php
Line 110 in 516db46
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
Is there any rhyme or reason behind this or would it be possible for me to make a PR to change that line to use this constant found here?
https://github.com/lightSAML/lightSAML/blob/b5e37b001c68da82bea8b2ca30230598368c51d1/src/LightSaml/SamlConstants.php#L69
Thanks!
Hi, basically I need to POST a SAML assertion to a predefined URL that I was given, in order for the users of my app to login automatically to the SP, I have already followed the readme and already done the configuration setup but I am not sure how can I create the assertion in order to make a post.
Cheers.
Hello, I'm trying to configure my Laravel Nova app as an SAML IdP with your package. It's been quite intuitive to configure, great job!
However I'm interested in doing the Idp initiated flow but so far I'm only able to do the SP initiated flow. Is there any way to do that? Am I missing something?
PS.: I don't quite understand the hidden inputs embedded with the @samlidp directive, but isn't that their purpose, to trigger the SSO flows when the user tries to login?
Hello
How would be an approach to authenticate the user (sso) via the register page?
The normal flow is: some user tries to access a protected route on the broker, the broker redirects the user to the sso url (login page, in this case) on the idP, the user logs in, the idP redirects the user back to the broker and everything works perfect.
But sometimes the user will not be registered on the idP, and i would like to allow a user registration page, and after the registration the user should be redirected back to the broker, same as login.
Considering the package implementation, it should work the same as the login page (because of the sso listener on the authenticated event), as long as you keep the SAMLRequest
and RelayState
query strings on the url. When the broker redirects to the idP, those parameters exists on the url. But, in the idP, if you click a register button or something like that, the parameters will not pass to the next request, unless you do something.
So managed to save the saml parameters in the session as soon as the user enters the login page, so i can use it to populate the register button links with the query parameters.
Something like this in the LoginController
public function __construct()
{
$this->middleware('guest')->except('logout');
session()->forget(['keepSAMLRequest', 'keepRelayState']);
if (request()->filled('SAMLRequest') && ! request()->is('saml/logout')) {
session([
'keepSAMLRequest' => request('SAMLRequest'),
'keepRelayState' => request('RelayState'),
]);
}
}
Using this, i can use the register buttons like this:
<a href="{{ route('register', ['SAMLRequest' => session('keepSAMLRequest'), 'RelayState' => session('keepRelayState') ]) }}">Register</a>
And then the parameters would be in the register page request. I just would have to use the @samlidp
on the register page.
I think this would work, but i would have to clean the session on the authenticated event, and there is already a listener on this event that aborts the request, so i would have to make sure my listener runs before the Sso listener, and i think this starts to be complicated.
I also think messing with session is kinda bad in this case. And it is kinda weird that i would have manually insert the parameters each register button url (same for forgot password, etc).
Anyway, How would be an approach to authenticate the user (sso) via the register, password recovery, etc? Did any of you manage to achieve something like this?
There is a clean/correct way to do this?
Thanks for creating the package to turn a Laravel site into an IdP. SSO is a pretty new field to me. Can you recommend any packages to make other sites to be SP? I did some research, most of the places mentioned about https://github.com/aacotroneo/laravel-saml2 or https://github.com/miniOrangeDev/saml-laravel-free. thanks.
I am using Laravel 8 in production env.
I have nginx as webserver and when my request is made to https://domain.tld/saml/metadata
A 500 Server Error
is thrown.
After checking the reason for this at log file. I saw.
After opening this metadata.blade.php file in my editor
VS Code indicates an error at line 1. But when I close it. VS Code does not show any indication of error.
On my localmachine. Everything works well. Below is the image from my local machine with XAMP Apache.
Did anyone ever experienced this kind of issue with this package, Please let me know how to solve it.
Thanks in advance.
In a nutshell, is it possible to initiate the SAML SSO flow from the IdP?
Currently it looks as if the SP has to make a request to your Laravel application for the request parameters to be filled out?
Is there a way that a logged in user at the IdP end could press a button and initiate the SAML SSO flow with the SP?
Use the following command to create new certificate and private key for yoru IdP.
php artisan samlidp:cert --days 7300 --keyname key.pem --certname cert.pem
--days
Number of days to add from today as the expiration date
Default: 7300
--keyname
Full name of the certificate key file
Default: key.pem
--certname
Full name to the certificate file
Default: cert.pem
This command will do something similar to the following
cd storage/samlidp
openssl req -x509 -sha256 -nodes -days 7300 -newkey rsa:2048 -keyout key.pem -out cert.pem
I've setup the logout to logout after slo (config(samlidp.logout_after_slo)
) and because no service provider has a valid setup with a logout procedure the session also does not save a variable saml.slo
(see https://github.com/codegreencreative/laravel-samlidp/blob/master/src/Http/Controllers/LogoutController.php#L30). And in return the logout redirects to the /saml/logout
url again (see https://github.com/codegreencreative/laravel-samlidp/blob/master/src/Listeners/SamlLogout.php#L19).
Basically there are two solutions for that:
I can create a PR if you tell me which solution you prefer. My preference is to set the session variable if not set already.
I have installed codegreencreative / laravel-samlidp on my login portal server. I am looking for a package or instruction for how to configure my laravel application servers as a service provider. Which package is compatible with codegreencreative / laravel-samlidp? Or what advice can be given on this?
I'm getting the following error when a SP attempts to log in:
Invalid PEM encoded certificate
It's coming from vendor\forlabs\lightsaml\src\LightSaml\Credential\X509Certificate.php:82.
I've edited that file directly and added some debug lines (\Log::debug('PEM:'); \Log::debug($data)
). I can see this function being called twice when a user is attempting to log in. The second time the file is empty, which results in the error.
This is being called from vendor\codegreencreative\laravel-samlidp\src\Jobs\SamlSso.php:124. If I set samlidp.encrypt_assertion
to false I get around it, but my SP fails with invalidFederatedIdentityActionMessage
- I think they need me to be encrypting.
Any idea? I saw the other issue with a similar problem where the suggested fix is to downgrade to PHP 7.3. I tried that, but same problem, but I didn't really expect that to work as the PEM file CAN be read, it's just empty on the second attempt.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.