ory / hydra

The most scalable and customizable OpenID Certified™ OpenID Connect and OAuth Provider on the market. Become an OpenID Connect and OAuth2 Provider over night. Broad support for related RFCs. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=hydra
Apache License 2.0
15.46k stars 1.48k forks source link

Add SAML2 Bearer Assertion Grant Type #1519

Closed lpotherat closed 3 years ago

lpotherat commented 5 years ago

Is your feature request related to a problem? Please describe.

I'm implementing SSO to allow users to be authenticated once on multiple websites of the same company. I've choosen SAML2 (with SimpleSamlPhp to handle the SAML2 protocol), and I've also choosen Hydra because of the way it works with login and consent app. Now, the different websites need the AccessToken to access webservices related to the user.

Describe the solution you'd like

I would like to configure Hydra to handle the SAML2 Bearer Assertion Grant Type, so the websites could get an AccessToken from hydra after being authenticated via SAML2.

Describe alternatives you've considered

I considered implementing the SAML2 protocol behind Hydra, but it does not provide the SSO experience needed, because the login app must be stateless (from doc here

The endpoint handler at /login must not remember previous sessions. This task is solved by ORY Hydra. If the REST API call tells you to show the login ui, you must show it. If the REST API tells you to not show the login ui, you must not show it. Again, do not implement any type of session here.

)

Additional context

I saw an ooold conversation about a similar problem where the answer was the alternative (Discussion

This is now possible by implementing a consent endpoint that understands SAML :) )

By the way, thanks for all the work !

aeneasr commented 5 years ago

Thanks - I think this is a reasonable addition and complexity is also reasonable as all we need to do is decode the SAML assertion and use the principal (or subject) as the authenticated identity.

Basically, using the SAML assertion would skip the login redirection dance at hydra and redirect the end user directly to the consent endpoint. You could theoretically achieve the same by adding the saml assertion as a custom query param to the initial oauth2 url /oauth2/auth?...&saml_token=... and use that in your login app to authenticate the user directly (remember should always be false in that case).

This would obviously defeat a lot of the dances from openid connect - basically prompt would become meaningless which is what we imply with:

The endpoint handler at /login must not remember previous sessions. This task is solved by ORY Hydra. If the REST API call tells you to show the login ui, you must show it. If the REST API tells you to not show the login ui, you must not show it. Again, do not implement any type of session here.

but that would also be the case if we'd support the SAML grant type in hydra itself.

However, we are currently ice-boxing new features for hydra as we're focusing all resources on github.com/ory/hive so it will most likely take a significant amount of time before we could add this feature.

To land this feature in reasonable time, you could give it a shot yourself with a PR at fosite and hydra. Alternatively, you could convince your company to become a sponsor of ours which helps with paying additional maintainers to address features like these :)

lpotherat commented 5 years ago

Thanks a lot for the quick and clear reply !

I will try the saml_token in GET parameter of /oauth2/auth endpoint, I will also try to work on a PR (no guarantee, I'm quite new to Go and Oauth2 / SAML2 processes), but after my holidays next week :) .

I'll also give a shot to my boss to become a Sponsor as well.

Thanks again

sandert-k8s commented 4 years ago

Hi there,

We want to achieve exactly the same thing as @lpotherat , Simplesamlphp with Hydra. Did you manage to implement this? And if so, how did you do this? And if not, did you find another solution to combine SAML and Oauth2? Thanks!

lpotherat commented 4 years ago

@sandert98 I used a custom Provider based on the cirrusidentity/simplesamlphp-module-authoauth2 module for simplesamlphp. Added a custom class into /simplesamlphp/simplesamlphp/modules/authoauth2/lib/Auth/Source

<?php

namespace SimpleSAML\Module\authoauth2\Auth\Source;

use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
use SimpleSAML\Logger;
use SimpleSAML\Module\authoauth2\ConfigTemplate;

/**
 * Include accessToken into user payload
 */
class MyOAuth2 extends OAuth2
{

    public function __construct(array $info, array $config)
    {
        parent::__construct($info, $config);
    }

    /**
     * Add accesstoken in attributes to share with partners
     * @param AccessToken $accessToken
     * @param AbstractProvider $provider
     * @param array $state
     */
    public function postFinalStep(AccessToken $accessToken, AbstractProvider $provider, &$state)
    {
        $state['Attributes']['accessToken'] = [$accessToken->getToken()];
    }
}

This class transfer the accessToken into the SAML2 state, which makes it available to SAML2 clients.

Then, use it in your Hydra configuration of SimpleSamlPHP with this into authsources : "authoauth2:MyOAuth2"

Warning though, it breaks Oauth2 since the accessToken is transferred accross systems ! So, use it carefully with this in mind...

vinckr commented 4 years ago

Hey @lpotherat, you probably have not looked at this in some time, but is this resolved yet? Would you be open to make a PR with your fix? Any contribution is much appreciated, thanks!

lpotherat commented 4 years ago

Hi, I haven't looked at this issue at all, because of my lack of knowledge in go, docker and SAML2 Core... I tried to get and build hydra from sources to develop on it a couple month ago without success (with initiations to go etc...).

So I don't have a PR, and I was maybe too optimistic last year on my workload.

yordis commented 4 years ago

@aeneasr any updates on this feature?

aeneasr commented 3 years ago

I am closing this issue as it has not received any engagement from the community or maintainers in a long time. That does not imply that the issue has no merit. If you feel strongly about this issue

We are cleaning up issues every now and then, primarily to keep the 4000+ issues in our backlog in check and to prevent maintainer burnout. Burnout in open source maintainership is a widespread and serious issue. It can lead to severe personal and health issues as well as enabling catastrophic attack vectors.

Thank you to anyone who participated in the issue! 🙏✌️