|
1 | 1 | # Test SAML IdP |
2 | 2 |
|
3 | | -This is a very simple SAML Identity Provider (IdP) you can use to test your SAML |
4 | | -Service Provider (SP) implementation with. It's very basic right now, it allows |
5 | | -you to login and respond with a signed SAML response. It also supports SAML Logout. |
| 3 | + |
| 4 | +[](https://github.com/paulcwatts/test-saml-idp/blob/main/LICENSE) |
| 5 | + |
| 6 | +This is a basic SAML Identity Provider (IdP) you can use to test a SAML |
| 7 | +Service Provider (SP) implementation. It allows you to download metadata, to log in, |
| 8 | +and to respond with a signed SAML response. It also supports SAML Single Log Out. |
6 | 9 |
|
7 | 10 | **This is not intended to be, nor will it ever be, a fully functional |
8 | 11 | SAML IdP implementation.** It's only meant to stand up as a quick test IdP |
9 | 12 | for use in manual or automated testing. |
10 | 13 |
|
11 | | -# TODO: Configuration |
| 14 | +# Quick Setup |
12 | 15 |
|
13 | | -There are three things you need to configure: |
| 16 | +The easiest way to get up and going is to use the pre-built Docker image. |
14 | 17 |
|
15 | | -1. The base URL used by the server; |
16 | | -1. The SAML key and certificate used to sign the response; |
17 | | -2. The list of username/passwords that are considered valid. |
| 18 | +## Running the server |
18 | 19 |
|
19 | | -# TODO: Setup |
| 20 | +1. Create a metadata certification for development. This will also be used |
| 21 | +to sign SAML responses. |
| 22 | +```bash |
| 23 | +openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout metadata.key -out metadata.crt |
| 24 | +``` |
| 25 | +2. Create a `.env` file and add the following contents: |
| 26 | +```env |
| 27 | +SAML_IDP_ENTITY_ID=http://localhost:8000/ |
| 28 | +SAML_IDP_METADATA_CERT_FILE=/etc/saml/metadata.crt |
| 29 | +SAML_IDP_METADATA_KEY_FILE=/etc/saml/metadata.key |
| 30 | +SAML_IDP_USERS=[{"username": "myuser", "password": "mypass"}] |
| 31 | +``` |
| 32 | +3. Run the Docker image: |
| 33 | +```bash |
| 34 | +docker run --rm --env-file .env -p 8000:8000 \ |
| 35 | + --read-only -v <local path to metadata.crt/key>:/etc/saml \ |
| 36 | + paulcwatts/test-saml-idp |
| 37 | +``` |
| 38 | +4. Go to http://localhost:8000 |
20 | 39 |
|
21 | | -# TODO: Create a metadata certificate for development |
| 40 | +You can click "Sign in" and login with the credentials you provided in the |
| 41 | +env file. (Username: `myuser`, password: `mypass`). |
22 | 42 |
|
| 43 | +## Testing with a service provider |
| 44 | + |
| 45 | +If you don't have a SAML Service Provider handy, you can use |
| 46 | +the [RSA Test Service Provider](https://sptest.iamshowcase.com/instructions#spinit) |
| 47 | +to test that your IdP is running correctly. |
| 48 | + |
| 49 | +1. Download the IdP metadata from http://localhost:8000/metadata.xml: |
23 | 50 | ```bash |
24 | | -openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout metadata.key -out metadata.crt |
| 51 | +curl http://localhost:8000/metadata.xml >metadata.xml |
25 | 52 | ``` |
| 53 | +2. Go to https://sptest.iamshowcase.com/instructions#spinit and upload that file. |
| 54 | +Copy the provided URL to the clipboard. |
| 55 | +3. Open a browser window and paste that URL into the address bar. You should be redirected |
| 56 | +to the Test IDP. |
| 57 | +4. Log in using the credentials you used before (Username: `myuser`, password: `mypass`). |
| 58 | + |
| 59 | +If everything works, you will be redirected back to the Service Provider |
| 60 | +with the Subject Information and Authentication Details. |
| 61 | + |
| 62 | +# Deployment |
26 | 63 |
|
| 64 | +This was written so you can test your federated login functionality without having |
| 65 | +to use an external service. To do that, you'll probably want to deploy |
| 66 | +it on your own infrastructure. Here are some considerations you'll want to think |
| 67 | +about: |
27 | 68 |
|
28 | | -# TODO: Docker |
| 69 | +1. You'll want to change the SAML entity ID to something less generic. It should be specific |
| 70 | +to your deployment, such as the URL of the deployed service. |
| 71 | +2. You will want to deploy the metadata certificate and key in a secure location, |
| 72 | +such as [Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret/). |
| 73 | +3. If you plan on supporting Single Log Out, you'll need to add a URL to which |
| 74 | +the service will redirect after logging out (see `SAML_IDP_LOGOUT_URL` under |
| 75 | +[Configuration Options](#configuration-options)). |
| 76 | + |
| 77 | +# Configuration Options |
| 78 | + |
| 79 | +Configuration is provided via environment variables. |
| 80 | + |
| 81 | +| Environment Variable | Description | Required? | |
| 82 | +|-----------------------|-------------------------------------------------------------------------------------------|---------------------| |
| 83 | +| SAML_ID_ENTITY_ID | The Entity ID specified in the SAML IdP metadata. This must be a URL. | Yes | |
| 84 | +| SAML_IDP_METADATA_CERT | The path to the SAML signing certificate file. | Yes | |
| 85 | +| SAML_IDP_METADATA_KEY | The path to the SAML signing private key file. | Yes | |
| 86 | +| SAML_IDP_USERS | The list of user credentials to accept | Yes | |
| 87 | +| SAML_IDP_BASE_URL | The base URL to use for the signin/logout endpoints. By default, it is the base host URL. | No | |
| 88 | +| SAML_IDP_LOGOUT_URL | The URL to redirect to after Single Log Out | Only if SLO is used | |
| 89 | +| SAML_IDP_SHOW_USERS | If True, display a table of credentials on the login screen. Defaults to False. | No | |
| 90 | +| SAML_IDP_ROUTER_PREFIX | If set, adds a prefix to all URLs. Default is empty. | No | |
| 91 | + |
| 92 | +## Defining Users |
| 93 | + |
| 94 | +You can define credentials that are accepted using the `SAML_IDP_USERS` environment |
| 95 | +variable. (You don't *have* to specify any users, but if you don't you can't log in |
| 96 | +and this service isn't very useful.) The format of `SAML_IDP_USERS` is a JSON list, |
| 97 | +with each element in the list being the following format: |
| 98 | + |
| 99 | +```typescript |
| 100 | +interface User { |
| 101 | + username: string; |
| 102 | + password: string; |
| 103 | + attributes?: Record<string, string>; |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +Or if you prefer, in Python: |
| 108 | + |
| 109 | +```python |
| 110 | +class User(TypedDict): |
| 111 | + username: Required[str] |
| 112 | + password: Required[str] |
| 113 | + attributes: NotRequired[dict[str, str]] |
| 114 | +``` |
29 | 115 |
|
30 | | -# TODO: Development |
| 116 | +If `attributes` is specified, the service will include those as SAML Attributes |
| 117 | +in the AuthnResponse. |
0 commit comments