mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-09 23:55:12 +00:00
## Todos for release - [x] Configure Env in docs project on vercel - [x] Configure Root Path in the docs project on vercel - [ ] Remove old CSP https://github.com/zitadel/website/pull/1592 ## What we did This pull request migrates the project documentation from the old `docs/` directory to the new `apps/docs/` directory, introduces a new documentation system built with Next.js and Fumadocs, and updates all relevant references, configuration files, and documentation to reflect this change. It also adds new configuration and ignore files for the new documentation app, updates CI and linting to exclude the new docs from certain checks, and revises the contributing guidelines accordingly. **Documentation System Migration and New Docs App** * Migrated all documentation from `docs/` to `apps/docs/`, and updated all references in `README.md`, `CONTRIBUTING.md`, and other files to point to the new location. [[1]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L585-L640) [[2]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L660-R607) [[3]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L740-R687) [[4]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L2-R3) [[5]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L30-R30) * Added a new Next.js/Fumadocs-based documentation app under `apps/docs/`, including core app files, layouts, routing, search API, and a comprehensive `README.md` with development and contribution instructions. [[1]](diffhunk://#diff-5a1b07344a2c1b4d3f37b23ff1388b62cd9f57dea3c1cd23d8a0412b7602b132R1-R74) [[2]](diffhunk://#diff-462b9ad1eabbb7d1c29bb9c36e4931eb180fd7190900e6d2babf8f4d66ad1c28R1-R39) [[3]](diffhunk://#diff-e16ae25660ded787b10ac35dea96d5ecaacf895dae0afc8a9bd4382dc79a8c87R1-R7) [apps/docs/app/[[...slug]]/layout.tsxR1-R81](diffhunk://#diff-59e08acde4e805b7aeccef1dcf98f1d71dfc550777e6b9402085cee0e9fa4e0aR1-R81), [apps/docs/app/[[...slug]]/page.tsxR1-R79](diffhunk://#diff-e5df3f80d0fa01e12d63d81f29c57a9d14e846c78fd3beabb2ef768e38fd9580R1-R79), [[4]](diffhunk://#diff-389b34918e040cacaa87cd7201ffa462cc2b0b716736f537e3d3c660ac69353bR1-R7) [[5]](diffhunk://#diff-d3b03416d1c457b19f1c27b26f2db741412df841b875c26ccadc36e4522247f4R1-R29) [[6]](diffhunk://#diff-c8fb8339570a5305809be7c618e14705fd86390dc278e6ce8ba224a7bc8b0c3cR1-R25) **Configuration and Tooling Updates** * Updated `.github/workflows/codeql.yml`, `.golangci.yaml`, and `.github/dependabot.yml` to properly handle the new docs app: excluded `apps/docs` from certain checks, added npm dependency updates for the docs app, and excluded generated content. [[1]](diffhunk://#diff-12783128521e452af0cfac94b99b8d250413c516ec71fe6d97dbea666ff7ba27L8-R14) [[2]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R5-R6) [[3]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R126-R129) [[4]](diffhunk://#diff-dd4fbda47e51f1e35defb9275a9cd9c212ecde0b870cba89ddaaae65c5f3cd28R89-R106) * Updated `.devcontainer/devcontainer.json` to use the latest Go 1.25.3 version for consistency. **Licensing and Miscellaneous** * Added `apps/docs/` to the list of licensed directories in `LICENSING.md`. These changes ensure the documentation is now maintained in a modern, scalable system and all project tooling is updated to support the new structure. --------- Co-authored-by: Federico Coppede <[email protected]>
168 lines
7.1 KiB
Plaintext
168 lines
7.1 KiB
Plaintext
---
|
|
title: Support for the SAML Standard in a Custom Login UI
|
|
sidebar_label: SAML Standard
|
|
---
|
|
|
|
To build your own login ui for your own application it is not necessary to have the SAML standard included or any additional work that has to be done.
|
|
However, it might make sense, if you want to connect your login to different applications especially if they are not in your control and they rely on the standard.
|
|
|
|
The following flow shows you the different components you need to enable SAML for your login.
|
|

|
|
|
|
1. Your application makes an SAML request to your login UI
|
|
2. The login UI proxies the request to the ZITADEL API.
|
|
3. The ZITADEL API parses the request and does what it needs to interpret certain parameters (e.g., binding, nameID policy, etc.)
|
|
4. Redirect to a predefined, relative URL of the login UI that includes the samlrequest ID ("/login?authRequest="), configurable per application.
|
|
5. Request to ZITADEL API to get all the information from the SAML request. This is optional and only needed if you like to get all the parsed information from the samlrequest-
|
|
6. Authenticate the user in your login UI by creating and updating a session with all the checks you need.
|
|
7. Finalize the SAML request by sending the session to the request, you will get the URL to redirect to or the body in the response
|
|
8. Redirect to your application with the URL or call the application with HTTP Post with the content you got in the previous request
|
|
9. All SAML-specific endpoints have to be accepted in the Login UI and should be proxied and sent to the ZITADEL API
|
|
|
|
## Example
|
|
|
|
Let's assume you host your login UI on the following URL:
|
|
```
|
|
https://login.example.com
|
|
```
|
|
|
|
## SAML Request
|
|
|
|
A user opens your application and is unauthenticated, the user will then be redirected to your login with the following SAML Request:
|
|
```
|
|
https://login.example.com/saml/v2/SSO?SAMLRequest=nJLRa9swEMb%2FFXHvjmVTY0fUhqxhLNCtoc72sLerdFkEspTpzt3634%2BkGXQw8tBX6X76vk%2F33TJO4WhWsxziI%2F2ciUX9nkJkc7roYc7RJGTPJuJEbMSacfX53tQLbZCZsvgU4Q1yvM4cc5JkUwC1WffgXdHW1c2%2BclVtK6yc68hVnWvssqVm79p23za01E%2BuA%2FWNMvsUe6gXGtSGeaZNZMEoPdS6bgpdFbrd6aW50abuFk3Tfge1JhYfUc7kQeRoyjIki%2BGQWEynO12ebJfPdTmOD6BWf0PdpcjzRHmk%2FOwtfX28%2Fy%2BvLzxaBrW9pPvgo%2FPxx%2FWveHodYvNpt9sW24dxB8N5HeacLauPKU8o1x85nXhX7M%2BjhqJ4eYHhis%2BJBB0K3pZvpIZLDb7gRJv1NgVvX94hLxkje4oCahVC%2BnWXCYV6kDwTlMOr5L9lG%2F4EAAD%2F%2Fw%3D%3D&RelayState=CncN92gdF6is7bak63thXOsn0MmJn7CLQeGKWaXZo2L8nJN0sPEHbb4I
|
|
```
|
|
|
|
The SAML request includes all the relevant information for the SAML standard, which includes the RelayState, the used binding and other information.
|
|
|
|
You now have to proxy the SAML request from your own UI to the SSO Endpoint of ZITADEL.
|
|
For more information, see [OIDC Proxy](./login-app#oidc-proxy) for the necessary headers.
|
|
|
|
<Callout>
|
|
The version and the optional custom URI for the available login UI is configurable under the application settings.
|
|
</Callout>
|
|
|
|
Read more about the [SSO Endpoint Documentation](/apis/saml/endpoints#sso-endpoint)
|
|
|
|
The endpoint will redirect you to the domain of your UI on the path /login and add the SAML Request ID as parameter.
|
|
```https://login.example.com/login?authRequest=V2_224908753244265546```
|
|
|
|
### Get SAML Request by ID
|
|
|
|
With the ID from the redirect before you will now be able to get the information of the SAML request.
|
|
[Get SAML Request By ID Documentation](/reference/api/saml/zitadel.saml.v2.SAMLService.GetSAMLRequest)
|
|
|
|
```bash
|
|
curl --request GET \
|
|
--url https://${CUSTOM_DOMAIN}/v2/saml/saml_requests/V2_224908753244265546 \
|
|
--header 'Authorization: Bearer '"$TOKEN"''
|
|
```
|
|
|
|
Response Example:
|
|
|
|
```json
|
|
{
|
|
"samlRequest": {
|
|
"id": "V2_224908753244265546",
|
|
"creationDate": "2023-07-28T13:47:43.471505Z",
|
|
"issuer": "https://myapp.example.com",
|
|
"assertionConsumerService": "https://myapp.example.com/acs",
|
|
"relayState": "CncN92gdF6is7bak63thXOsn0MmJn7CLQeGKWaXZo2L8nJN0sPEHbb4I",
|
|
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Perform Login
|
|
|
|
After you have initialized the SAML flow you can implement the login.
|
|
Implement all the steps you like the user to go trough by [creating](/reference/api/session/zitadel.session.v2.SessionService.CreateSession) and [updating](/reference/api/session/zitadel.session.v2.SessionService.SetSession) the user-session.
|
|
|
|
Read the following resources for more information about the different checks:
|
|
- [Username and Password](./username-password)
|
|
- [External Identity Provider](./external-login)
|
|
- [Passkeys](./passkey)
|
|
- [Multi-Factor](./mfa)
|
|
|
|
### Finalize SAML Request
|
|
|
|
To finalize the SAML request and connect an existing user session with it, you have to update the SAML Request with the session token.
|
|
On the create and update user session request you will always get a session token in the response.
|
|
|
|
The latest session token has to be sent to the following request:
|
|
|
|
Read more about the [Finalize SAML Request Documentation](/reference/api/saml/zitadel.saml.v2.SAMLService.CreateResponse)
|
|
|
|
Make sure that the authorization header is from an account which is permitted to finalize the SAML Request through the `IAM_LOGIN_CLIENT` role.
|
|
```bash
|
|
curl --request POST \
|
|
--url ${CUSTOM_DOMAIN}/v2/saml/saml_requests/V2_224908753244265546 \
|
|
--header 'Accept: application/json' \
|
|
--header 'Authorization: Bearer '"$TOKEN"''\
|
|
--header 'Content-Type: application/json' \
|
|
--data '{
|
|
"session": {
|
|
"sessionId": "225307381909694508",
|
|
"sessionToken": "7N5kQCvC4jIf2OuBjwfyWSX2FUKbQqg4iG3uWT-TBngMhlS9miGUwpyUaN0HJ8OcbSzk4QHZy_Bvvv"
|
|
}
|
|
}'
|
|
```
|
|
|
|
In the response you will get content which describe how to handle further steps from your login UI.
|
|
|
|
#### POST-Binding
|
|
|
|
Example Response POST-binding:
|
|
```json
|
|
{
|
|
"details": {
|
|
"sequence": "686",
|
|
"changeDate": "2023-07-31T08:09:19.314537Z",
|
|
"resourceOwner": "163840776801878273"
|
|
},
|
|
"url": "https://myapp.example.com/acs",
|
|
"binding": {
|
|
"post": {
|
|
"relayState": "CncN92gdF6is7bak63thXOsn0MmJn7CLQeGKWaXZo2L8nJN0sPEHbb4I",
|
|
"samlResponse": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPFJlc3Bv..."
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Which expects your client to do a POST call to the URL `https://myapp.example.com/acs` with the payload containing the following attributes:
|
|
|
|
```
|
|
RelayState: "CncN92gdF6is7bak63thXOsn0MmJn7CLQeGKWaXZo2L8nJN0sPEHbb4I",
|
|
SAMLResponse: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPFJlc3Bv..."
|
|
```
|
|
|
|
#### Redirect-Binding
|
|
|
|
Example Response Redirect-binding:
|
|
```json
|
|
{
|
|
"details": {
|
|
"sequence": "686",
|
|
"changeDate": "2023-07-31T08:09:19.314537Z",
|
|
"resourceOwner": "163840776801878273"
|
|
},
|
|
"url": "https://myapp.example.com/acs?RelayState=CncN92gdF6is7bak63thXOsn0MmJn7CLQeGKWaXZo2L8nJN0sPEHbb4I&SAMLResponse=PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPFJlc3Bv...",
|
|
"binding": {
|
|
"redirect": {}
|
|
}
|
|
}
|
|
```
|
|
|
|
Which expects your client to redirect to the url 'https://myapp.example.com/acs?RelayState=...&SAMLResponse=...' with all information as URL parameters.
|
|
|
|
### SAML Endpoints
|
|
|
|
All SAML relevant endpoints are provided by ZITADEL. In your login UI you just have to proxy them through and send them directly to the backend.
|
|
|
|
These are endpoints like:
|
|
- Metadata
|
|
- Certificate
|
|
- ACS
|
|
- etc
|