Skip to content

Commit 0957f59

Browse files
authored
Merge pull request #633 from nakaeeee/saml-auth
Support SAML authentication
2 parents 8112cd6 + 2db2ff4 commit 0957f59

19 files changed

+306
-4
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ There are some configs you need to change in the files below
172172
| HMD_LDAP_SEARCHATTRIBUTES | no example | LDAP attributes to search with |
173173
| HMD_LDAP_TLS_CA | `server-cert.pem, root.pem` | Root CA for LDAP TLS in PEM format (use comma to separate) |
174174
| HMD_LDAP_PROVIDERNAME | `My institution` | Optional name to be displayed at login form indicating the LDAP provider |
175+
| HMD_SAML_IDPSSOURL | `https://idp.example.com/sso` | authentication endpoint of IdP. for details, see [guide](docs/guides/auth.md#saml-onelogin). |
176+
| HMD_SAML_IDPCERT | `/path/to/cert.pem` | certificate file path of IdP in PEM format |
177+
| HMD_SAML_ISSUER | no example | identity of the service provider (optional, default: serverurl)" |
178+
| HMD_SAML_IDENTIFIERFORMAT | no example | name identifier format (optional, default: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`) |
179+
| HMD_SAML_GROUPATTRIBUTE | `memberOf` | attribute name for group list (optional) |
180+
| HMD_SAML_REQUIREDGROUPS | `Hackmd-users` | group names that allowed (use vertical bar to separate) (optional) |
181+
| HMD_SAML_EXTERNALGROUPS | `Temporary-staff` | group names that not allowed (use vertical bar to separate) (optional) |
182+
| HMD_SAML_ATTRIBUTE_ID | `sAMAccountName` | attribute map for `id` (optional, default: NameID of SAML response) |
183+
| HMD_SAML_ATTRIBUTE_USERNAME | `mailNickname` | attribute map for `username` (optional, default: NameID of SAML response) |
184+
| HMD_SAML_ATTRIBUTE_EMAIL | `mail` | attribute map for `email` (optional, default: NameID of SAML response if `HMD_SAML_IDENTIFIERFORMAT` is default) |
175185
| HMD_IMGUR_CLIENTID | no example | Imgur API client id |
176186
| HMD_EMAIL | `true` or `false` | set to allow email signin |
177187
| HMD_ALLOW_PDF_EXPORT | `true` or `false` | Enable or disable PDF exports |
@@ -234,7 +244,7 @@ There are some configs you need to change in the files below
234244

235245
| service | settings location | description |
236246
| ------- | --------- | ----------- |
237-
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap | environment variables or `config.json` | for signin |
247+
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap, saml | environment variables or `config.json` | for signin |
238248
| imgur, s3 | environment variables or `config.json` | for image upload |
239249
| google drive(`google/apiKey`, `google/clientID`), dropbox(`dropbox/appKey`) | `config.json` | for export and import |
240250

@@ -249,6 +259,7 @@ There are some configs you need to change in the files below
249259
| mattermost | `/auth/mattermost/callback` |
250260
| dropbox | `/auth/dropbox/callback` |
251261
| google | `/auth/google/callback` |
262+
| saml | `/auth/saml/callback` |
252263

253264
# Developer Notes
254265

config.json.example

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@
7575
"changeme": "See https://nodejs.org/api/tls.html#tls_tls_connect_options_callback"
7676
}
7777
},
78+
"saml": {
79+
"idpSsoUrl": "change: authentication endpoint of IdP",
80+
"idpCert": "change: certificate file path of IdP in PEM format",
81+
"issuer": "change or delete: identity of the service provider (default: serverurl)",
82+
"identifierFormat": "change or delete: name identifier format (default: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress')",
83+
"groupAttribute": "change or delete: attribute name for group list (ex: memberOf)",
84+
"requiredGroups": [ "change or delete: group names that allowed" ],
85+
"externalGroups": [ "change or delete: group names that not allowed" ],
86+
"attribute": {
87+
"id": "change or delete this: attribute map for `id` (default: NameID)",
88+
"username": "change or delete this: attribute map for `username` (default: NameID)",
89+
"email": "change or delete this: attribute map for `email` (default: NameID)"
90+
}
91+
},
7892
"imgur": {
7993
"clientID": "change this"
8094
},

docs/guides/auth.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,138 @@ To do this Click your profile icon --> Settings and privacy --> Mobile --> Sele
7575
HMD_GITHUB_CLIENTID=3747d30eaccXXXXXXXXX
7676
HMD_GITHUB_CLIENTSECRET=2a8e682948eee0c580XXXXXXXXXXXXXXXXXXXXXX
7777
````
78+
79+
### SAML (OneLogin)
80+
1. Sign-in or sign-up for an OneLogin account. (available free trial for 2 weeks)
81+
2. Go to the administration page.
82+
3. Select the **APPS** menu and click on the **Add Apps**.
83+
84+
![onelogin-add-app](images/auth/onelogin-add-app.png)
85+
86+
4. Find "SAML Test Connector (SP)" for template of settings and select it.
87+
88+
![onelogin-select-template](images/auth/onelogin-select-template.png)
89+
90+
5. Edit display name and icons for OneLogin dashboard as you want, and click **SAVE**.
91+
92+
![onelogin-edit-app-name](images/auth/onelogin-edit-app-name.png)
93+
94+
6. After that other tabs will appear, click the **Configuration**, and fill out the below items, and click **SAVE**.
95+
* RelayState: The base URL of your hackmd, which is issuer. (last slash is not needed)
96+
* ACS (Consumer) URL Validator: The callback URL of your hackmd. (serverurl + /auth/saml/callback)
97+
* ACS (Consumer) URL: same as above.
98+
* Login URL: login URL(SAML requester) of your hackmd. (serverurl + /auth/saml)
99+
100+
![onelogin-edit-sp-metadata](images/auth/onelogin-edit-sp-metadata.png)
101+
102+
7. The registration is completed. Next, click **SSO** and copy or download the items below.
103+
* X.509 Certificate: Click **View Details** and **DOWNLOAD** or copy the content of certificate ....(A)
104+
* SAML 2.0 Endpoint (HTTP): Copy the URL ....(B)
105+
106+
![onelogin-copy-idp-metadata](images/auth/onelogin-copy-idp-metadata.png)
107+
108+
8. In your hackmd server, create IdP certificate file from (A)
109+
9. Add the IdP URL (B) and the Idp certificate file path to your config.json file or pass them as environment variables.
110+
* config.json:
111+
````javascript
112+
{
113+
"production": {
114+
"saml": {
115+
"idpSsoUrl": "https://*******.onelogin.com/trust/saml2/http-post/sso/******",
116+
"idpCert": "/path/to/idp_cert.pem"
117+
}
118+
}
119+
}
120+
````
121+
* environment variables
122+
````
123+
HMD_SAML_IDPSSOURL=https://*******.onelogin.com/trust/saml2/http-post/sso/******
124+
HMD_SAML_IDPCERT=/path/to/idp_cert.pem
125+
````
126+
10. Try sign-in with SAML from your hackmd sign-in button or OneLogin dashboard (like the screenshot below).
127+
128+
![onelogin-use-dashboard](images/auth/onelogin-use-dashboard.png)
129+
130+
### SAML (Other cases)
131+
The basic procedure is the same as the case of OneLogin which is mentioned above. If you want to match your IdP, you can use more configurations as below.
132+
133+
* If your IdP accepts metadata XML of the service provider to ease configuraion, use this url to download metadata XML.
134+
* {{your-serverurl}}/auth/saml/metadata
135+
* _Note: If not accessable from IdP, download to local once and upload to IdP._
136+
* Change the value of `issuer`, `identifierFormat` to match your IdP.
137+
* `issuer`: A unique id to identify the application to the IdP, which is the base URL of your HackMD as default
138+
* `identifierFormat`: A format of unique id to identify the user of IdP, which is the format based on email address as default. It is recommend that you use as below.
139+
* urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress (default)
140+
* urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
141+
* config.json:
142+
````javascript
143+
{
144+
"production": {
145+
"saml": {
146+
/* omitted */
147+
"issuer": "myhackmd"
148+
"identifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
149+
}
150+
}
151+
}
152+
````
153+
* environment variables
154+
````
155+
HMD_SAML_ISSUER=myhackmd
156+
HMD_SAML_IDENTIFIERFORMAT=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
157+
````
158+
159+
* Change mapping of attribute names to customize the displaying user name and email address to match your IdP.
160+
* `attribute`: A dictionary to map attribute names
161+
* `attribute.id`: A primary key of user table for your HackMD
162+
* `attribute.username`: Attribute name of displaying user name on HackMD
163+
* `attribute.email`: Attribute name of email address, which will be also used for Gravatar
164+
* _Note: Default value of all attributes is NameID of SAML response, which is email address if `idfentifierFormat` is default._
165+
* config.json:
166+
````javascript
167+
{
168+
"production": {
169+
"saml": {
170+
/* omitted */
171+
"attribute": {
172+
"id": "sAMAccountName",
173+
"username": "displayName",
174+
"email": "mail"
175+
}
176+
}
177+
}
178+
}
179+
````
180+
* environment variables
181+
````
182+
HMD_SAML_ATTRIBUTE_ID=sAMAccountName
183+
HMD_SAML_ATTRIBUTE_USERNAME=nickName
184+
HMD_SAML_ATTRIBUTE_EMAIL=mail
185+
````
186+
187+
* If you want to controll permission by group membership, add group attribute name and required group (allowed) or external group (not allowed).
188+
* `groupAttribute`: An attribute name of group membership
189+
* `requiredGroups`: Group names array for allowed access to HackMD. Use vertical bar to separate for environment variables.
190+
* `externalGroups`: Group names array for not allowed access to HackMD. Use vertical bar to separate for environment variables.
191+
* _Note: Evaluates `externalGroups` first_
192+
* config.json:
193+
````javascript
194+
{
195+
"production": {
196+
"saml": {
197+
/* omitted */
198+
"groupAttribute": "memberOf",
199+
"requiredGroups": [ "hackmd-users", "board-members" ],
200+
"externalGroups": [ "temporary-staff" ]
201+
}
202+
}
203+
}
204+
````
205+
* environment variables
206+
````
207+
HMD_SAML_GROUPATTRIBUTE=memberOf
208+
HMD_SAML_REQUIREDGROUPS=hackmd-users|board-members
209+
HMD_SAML_EXTERNALGROUPS=temporary-staff
210+
````
211+
212+
39.6 KB
Loading
234 KB
Loading
120 KB
Loading
180 KB
Loading
71.5 KB
Loading
26.6 KB
Loading

lib/config/default.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ module.exports = {
9898
searchAttributes: undefined,
9999
tlsca: undefined
100100
},
101+
saml: {
102+
idpSsoUrl: undefined,
103+
idpCert: undefined,
104+
issuer: undefined,
105+
identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
106+
groupAttribute: undefined,
107+
externalGroups: [],
108+
requiredGroups: [],
109+
attribute: {
110+
id: undefined,
111+
username: undefined,
112+
email: undefined
113+
}
114+
},
101115
email: true,
102116
allowemailregister: true,
103117
allowpdfexport: true

0 commit comments

Comments
 (0)