-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Leif Battermann <[email protected]>
- Loading branch information
1 parent
f6e46c3
commit 8051138
Showing
6 changed files
with
153 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Update SAML/SCIM docs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,25 +26,6 @@ documentation answering your questions, look here! | |
- if you want to work on our saml/scim implementation and do not have access to [https://github.com/zinfra/backend-issues/issues?q=is%3Aissue+is%3Aopen+label%3Aspar] and [https://github.com/wireapp/design-specs/tree/master/Single%20Sign%20On], please get in touch with us. | ||
|
||
|
||
## design considerations | ||
|
||
### SCIM without SAML. | ||
|
||
Before https://github.com/wireapp/wire-server/pull/1200, scim tokens could only be added to teams that already had exactly one SAML IdP. Now, we also allow SAML-less teams to have SCIM provisioning. This is an alternative to onboarding via team-settings and produces user accounts that are authenticated with email and password. (Phone may or may not work, but is not officially supported.) | ||
|
||
The way this works is different from team-settings: we don't send invites, but we create active users immediately the moment the SCIM user post is processed. The new thing is that the created user has neither email nor phone nor a SAML identity, nor a password. | ||
|
||
How does this work? | ||
|
||
**email:** If no SAML IdP is present, SCIM user posts must contain an externalId that is an email address. This email address is not added to the newly created user, because it has not been validated. Instead, the flow for changing an email address is triggered in brig: an email is sent to the address containing a validation key, and once the user completes the flow, brig will add the email address to the user. We had to add very little code for this in this PR, it's all an old feature. | ||
|
||
When SCIM user gets are processed, in order to reconstruct the externalId from the user spar is retrieving from brig, we introduce a new json object for the `sso_id` field that looks like this: `{'scim_external_id': '[email protected]'}`. | ||
|
||
In order to find users that have email addresses pending validation, we introduce a new table in spar's cassandra called `scim_external_ids`, in analogy to `user`. We have tried to use brig's internal `GET /i/user&email=...`, but that also finds pending email addresses, and there are corner cases when changing email addresses and waiting for the new address to be validated and the old to be removed... that made this approach seem infeasible. | ||
|
||
**password:** once the user has validated their email address, they need to trigger the "forgot password" flow -- also old code. | ||
|
||
|
||
## operations | ||
|
||
### enabling / disabling the sso feature for a team | ||
|
@@ -226,35 +207,6 @@ This entry gets removed automatically when the corresponding idp is deleted. You | |
Clients can then ask for the default SSO code on `/sso/settings` and use it to initiate single sign-on. | ||
|
||
|
||
### troubleshooting | ||
|
||
#### gathering information | ||
|
||
- find metadata for team in table `spar.idp_raw_metadata` via cqlsh | ||
(since https://github.com/wireapp/wire-server/pull/872) | ||
|
||
- ask user for screenshots of the error message, or even better, for | ||
the text. the error message contains lots of strings that you can | ||
grep for in the spar sources. | ||
|
||
|
||
#### making spar work with a new IdP | ||
|
||
often, new IdPs work out of the box, because there appears to be some | ||
consensus about what minimum feature set everybody should support. | ||
|
||
if there are problems: collect the metadata xml and an authentication | ||
response xml (either from the browser http logs via a more technically | ||
savvy customer; FUTUREWORK: it would be nice to log all saml response | ||
xml files that spar receives in prod and cannot process). | ||
|
||
https://github.com/wireapp/saml2-web-sso supports writing [unit vendor | ||
compatibility | ||
tests](https://github.com/wireapp/saml2-web-sso/blob/ff9b9f445475809d1fa31ef7f2932caa0ed31613/test/Test/SAML2/WebSSO/APISpec.hs#L266-L329) | ||
against that response value. once that test passes, it should all | ||
work fine. | ||
|
||
|
||
### common misconceptions | ||
|
||
|
||
|
@@ -325,80 +277,3 @@ TODO (probably little difference between this and "user deletes herself"?) | |
#### delete via scim | ||
|
||
TODO | ||
|
||
|
||
## using the same IdP (same entityID, or Issuer) with different teams | ||
|
||
Some SAML IdP vendors do not allow to set up fresh entityIDs (issuers) | ||
for fresh apps; instead, all apps controlled by the IdP are receiving | ||
SAML credentials from the same issuer. | ||
|
||
In the past, wire has used the a tuple of IdP issuer and 'NameID' | ||
(Haskell type 'UserRef') to uniquely identity users (tables | ||
`spar.user_v2` and `spar.issuer_idp`). | ||
|
||
In order to allow one IdP to serve more than one team, this has been | ||
changed: we now allow to identity an IdP by a combination of | ||
entityID/issuer and wire `TeamId`. The necessary tweaks to the | ||
protocol are listed here. | ||
|
||
For everybody using IdPs that do not have this limitation, we have | ||
taken great care to not change the behavior. | ||
|
||
|
||
### what you need to know when operating a team or an instance | ||
|
||
No instance-level configuration is required. | ||
|
||
If your IdP supports different entityID / issuer for different apps, | ||
you don't need to change anything. We hope to deprecate the old | ||
flavor of the SAML protocol eventually, but we will keep you posted in | ||
the release notes, and give you time to react. | ||
|
||
If your IdP does not support different entityID / issuer for different | ||
apps, keep reading. At the time of writing this section, there is no | ||
support for multi-team IdP issuers in team-settings, so you have two | ||
options: (1) use the rest API directly; or (2) contact our customer | ||
support and send them the link to this section. | ||
|
||
If you feel up to calling the rest API, try the following: | ||
|
||
- Use the above end-point `GET /sso/metadata/:tid` with your `TeamId` | ||
for pulling the SP metadata. | ||
- When calling `POST /identity-provider`, make sure to add | ||
`?api_version=v2`. (`?api_version=v1` or no omission of the query | ||
param both invoke the old behavior.) | ||
|
||
NB: Neither version of the API allows you to provision a user with the | ||
same Issuer and same NamdID. RATIONALE: this allows us to implement | ||
'getSAMLUser' without adding 'TeamId' to 'UserRef', which in turn | ||
would break the (admittedly leaky) abstarctions of saml2-web-sso. | ||
|
||
|
||
### API changes in more detail | ||
|
||
- New query param `api_version=<v1|v2>` for `POST | ||
/identity-providers`. The version is stored in `spar.idp` together | ||
with the rest of the IdP setup, and is used by `GET | ||
/sso/initiate-login` (see below). | ||
- `GET /sso/initiate-login` sends audience based on api_version stored | ||
in `spar.idp`: for v1, the audience is `/sso/finalize-login`; for | ||
v2, it's `/sso/finalize-login/:tid`. | ||
- New end-point `POST /sso/finalize-login/:tid` that behaves | ||
indistinguishable from `POST /sso/finalize-login`, except when more | ||
than one IdP with the same issuer, but different teams are | ||
registered. In that case, this end-point can process the | ||
credentials by discriminating on the `TeamId`. | ||
- `POST /sso/finalize-login/:tid` remains unchanged. | ||
- New end-point `GET /sso/metadata/:tid` returns the same SP metadata as | ||
`GET /sso/metadata`, with the exception that it lists | ||
`"/sso/finalize-login/:tid"` as the path of the | ||
`AssertionConsumerService` (rather than `"/sso/finalize-login"` as | ||
before). | ||
- `GET /sso/metadata` remains unchanged, and still returns the old SP | ||
metadata, without the `TeamId` in the paths. | ||
|
||
|
||
### database schema changes | ||
|
||
[V15](https://github.com/wireapp/wire-server/blob/b97439756cfe0721164934db1f80658b60de1e5e/services/spar/schema/src/V15.hs#L29-L43) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.