Skip to content

docs: add authenticate with SAML guide#3684

Open
sixhobbits wants to merge 80 commits intoFusionAuth:mainfrom
ritza-co:draft-saml
Open

docs: add authenticate with SAML guide#3684
sixhobbits wants to merge 80 commits intoFusionAuth:mainfrom
ritza-co:draft-saml

Conversation

@sixhobbits
Copy link
Collaborator

The other part of #2854

@rideam
Copy link
Collaborator

rideam commented Jun 18, 2025

PR depends on sample repo https://github.com/ritza-co/fusionauth-example-saml.git being forked to the FusionAuth org

@rideam rideam requested a review from mooreds June 18, 2025 11:04
Copy link
Contributor

@mark-robustelli mark-robustelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I liked it. A few things to update and fix. Please also make sure it passes all the checks before requesting another review.


First, consider the simple case in which your website, Changebank.com, does its own authentication, as shown below. Only two parties are involved: the user and the website.

<SimpleAuthenticationDiagram alt="Simple authentication diagram" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we are using different diagrams than the ones we are already using for the Authentication Flow diagrams in the quickstarts? https://fusionauth.io/docs/quickstarts/quickstart-dotnet-web Can we keep them the same?


You can read more about [using FusionAuth as a SAML identity provider](/docs/lifecycle/authenticate-users/saml).

Finally, consider if Corpo were to act as the identity provider. In this case, there are four parties: the user, Changebank, FusionAuth acting as the SP, and Corpo acting as the IdP. This authentication flow is similar to the flow above, with one more level of redirection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above, you state that this is not the documentation for Corpo acting as the IdP. I don't think we need this section here.


The instructions above start FusionAuth using Kickstart, which automatically creates an example application with example users. Using Kickstart saves you from having to configure everything yourself.

You will need to change the authorized redirect URLs for this example.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we can't give them everything preconfigured?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark-robustelli Originally we had our own Docker compose and kickstart files in the example repository with this article. Dan asked us to switch to using the new DownloadWidget way of installing FusionAuth in this and all future guides, and having the user install Node.js on their physical machine. We can create a new kickstart folder for this article in https://github.com/FusionAuth/fusionauth-example-kickstart with everything set up perfectly, but Tatenda thought the configuration would be so close to one you already have the pull request would probably be rejected. If you'd like us to make one, please us know.


- Log in to your FusionAuth web interface at http://localhost:9011/admin with the credentials, `admin@example.com` and `password`.
- Browse to <Breadcrumb>Applications -> Start Here App -> Select -> Edit -> OAuth</Breadcrumb>.
- Change <InlineUIElement>Authorized redirect URLs</InlineUIElement> to `http://localhost:3000/auth/callback`. (Be sure to click the dropdown text that appears to confirm the entry.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Change <InlineUIElement>Authorized redirect URLs</InlineUIElement> to `http://localhost:3000/auth/callback`. (Be sure to click the dropdown text that appears to confirm the entry.)
- Change <InlineUIElement>Authorized redirect URLs</InlineUIElement> to `http://localhost:3000/auth/callback`. (Be sure to click the dropdown text that appears to confirm the entry. It should read Add URL http://localhost:3000/auth/callback)

- Log in to the Changebank website with `richard@example.com` and `password`.

![Change bank account page](/img/docs/lifecycle/examples/saml/accountIdp.png)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think you need some text here along the lines of. OK, you just logged in using basic username and password. No you need to configure FusionAuth to use SAML.

```

You can now browse to http://localhost:3000 and log in exactly the same way as before, except you're now using SAML. If you see an error that your account isn't registered, it's because you logged in previously with the administration account. Try to log in using an incognito browser window instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to have user go to logs and see that the user logged in using SAML since we have debug on.

You can now browse to http://localhost:3000 and log in exactly the same way as before, except you're now using SAML. If you see an error that your account isn't registered, it's because you logged in previously with the administration account. Try to log in using an incognito browser window instead.

If you see `oauth` in the browser address bar, don't worry; FusionAuth translates SAML to OAuth calls internally before returning. To satisfy yourself that SAML is indeed being used, edit the example application again in FusionAuth, disable SAML, and save. Now when you attempt to log in, you'll see the error, `The AuthnRequest contained an invalid issuer [passport-saml]. That Application does not have SAML enabled`.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logout does not work. I click it, get taken to the login page, but if I click login, it just goes through without asking for username and password. Logout should require new username and password entry.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark-robustelli here you had keep me signed in checked when you logged in
CleanShot-2025-07-16-16 48 09@2x


The code changes to the routes file are minimal, barely changing what is in the Passport documentation. You comment out the OAuth login route (because, in this example, the customer wanted to switch entirely to SAML), you add a SAML login route to direct the user to FusionAuth, and you use a callback handler to direct the logged in user to their account.

For more information on SAML in Passport, please see the [Passport-SAML](https://github.com/node-saml/passport-saml) and [Passport](https://github.com/jaredhanson/passport) documentation on GitHub.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be move up to where you mention Passport for the first time. I started looking for a link as I was reading and eventually found it here. It would have been good to know this existed before I started having to hunt.


If you see `oauth` in the browser address bar, don't worry; FusionAuth translates SAML to OAuth calls internally before returning. To satisfy yourself that SAML is indeed being used, edit the example application again in FusionAuth, disable SAML, and save. Now when you attempt to log in, you'll see the error, `The AuthnRequest contained an invalid issuer [passport-saml]. That Application does not have SAML enabled`.

## Explanation Of The New Code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these explanations should be up by the code or sections they are used in. I made some comments above about what does this do and why are we doing this. This section explains some of those. Should be closer in the document to where they are used.


While SAML allows the identity provider to sign both the response to a request (`wantAuthnResponseSigned`) and assertions in the response (`wantAssertionsSigned`), some providers, like FusionAuth, are limited to signing only one or the other. Signing both is the most secure configuration, but since you're forced to choose, signing the whole response is safer than only the assertions. You choose to sign the response by changing the <InlineUIElement>Signature location</InlineUIElement> while configuring SAML in FusionAuth.

The code changes to the routes file are minimal, barely changing what is in the Passport documentation. You comment out the OAuth login route (because, in this example, the customer wanted to switch entirely to SAML), you add a SAML login route to direct the user to FusionAuth, and you use a callback handler to direct the logged in user to their account.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the example you have us replace the line, here you say it should have been commented out. Don't think it matters which, but should be consistant.

@rideam rideam requested a review from mark-robustelli July 16, 2025 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants