Skip to content

Commit a5a94e4

Browse files
Clinton WerthClinton Werth
authored andcommitted
update auth read me. Add seed file for ldap.
1 parent fc43d31 commit a5a94e4

9 files changed

Lines changed: 127 additions & 64 deletions

File tree

Dockerfile

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ COPY plugins/arcgis/service/ ./
3838
RUN npm run build
3939
RUN npm pack
4040

41-
FROM node:20.11.1 AS build-imageserviceplugin
42-
WORKDIR /imageserviceplugin
43-
COPY plugins/image/service/package*.json ./
44-
RUN npm install
45-
COPY --from=build-service /service /imageserviceplugin/node_modules/@ngageoint/mage.service
46-
RUN rm -rf /imageserviceplugin/node_modules/@ngageoint/mage.service/node_modules/mongoose
47-
COPY plugins/image/service/ ./
48-
RUN npm run build
49-
RUN npm pack
41+
# FROM node:20.11.1 AS build-imageserviceplugin
42+
# WORKDIR /imageserviceplugin
43+
# COPY plugins/image/service/package*.json ./
44+
# RUN npm install
45+
# COPY --from=build-service /service /imageserviceplugin/node_modules/@ngageoint/mage.service
46+
# RUN rm -rf /imageserviceplugin/node_modules/@ngageoint/mage.service/node_modules/mongoose
47+
# COPY plugins/image/service/ ./
48+
# RUN npm run build
49+
# RUN npm pack
5050

5151
FROM node:20.11.1 AS build-sftpserviceplugin
5252
WORKDIR /sftpserviceplugin
@@ -74,7 +74,6 @@ COPY --from=build-arcwebplugin /arcgiswebplugin/ngageoint*.tgz /arcgiswebplugin/
7474
COPY --from=build-arcserviceplugin /arcgisserviceplugin/ngageoint*.tgz /arcgisserviceplugin/
7575
COPY --from=build-sftpserviceplugin /sftpserviceplugin/ngageoint*.tgz /sftpserviceplugin/
7676
COPY --from=build-sftpwebplugin /sftpwebplugin/ngageoint*.tgz /sftpwebplugin/
77-
COPY --from=build-imageserviceplugin /imageserviceplugin/ngageoint*.tgz /imageserviceplugin/
7877

7978
WORKDIR /instance
8079
RUN ls -la ../sftpwebplugin
@@ -84,7 +83,6 @@ RUN npm install ../sftpwebplugin/ngageoint-mage.sftp.web*.tgz
8483
RUN npm install ../sftpserviceplugin/ngageoint-mage.sftp.service*.tgz
8584
RUN npm install ../arcgiswebplugin/ngageoint*.tgz
8685
RUN npm install ../arcgisserviceplugin/ngageoint*.tgz
87-
RUN npm install ../imageserviceplugin/ngageoint*.tgz
8886

8987

9088
ENV NODE_PATH=./node_modules

docker/auth-idp/docker-compose.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,8 @@ services:
2626
- 389:389
2727
- 636:636
2828
volumes:
29-
- type: bind
30-
source: ./ldap/db
31-
target: /var/lib/ldap
32-
- type: bind
33-
source: ./ldap/config
34-
target: /etc/ldap/slapd.d
29+
- ./ldapseed.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-bootstrap.ldif
30+
command: --copy-service
3531
networks:
3632
- ldap.mage.net
3733

docker/auth-idp/ldap/config/.gitkeep

Whitespace-only changes.

docker/auth-idp/ldap/db/.gitkeep

Whitespace-only changes.

docker/auth-idp/ldapseed.ldif

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
dn: ou=Field Agents,dc=wgd,dc=com
2+
objectClass: organizationalUnit
3+
ou: Field Agents
4+
5+
dn: uid=batman,ou=Field Agents,dc=wgd,dc=com
6+
objectClass: inetOrgPerson
7+
uid: batman
8+
sn: Batman
9+
cn: Bruce Wayne
10+
userPassword: i heart alfred
11+
mail: Bruce.wayne@wgd.com
12+
13+
dn: uid=robin,ou=Field Agents,dc=wgd,dc=com
14+
objectClass: inetOrgPerson
15+
uid: robin
16+
sn: Robin
17+
cn: Dick Grayson
18+
userPassword: i heart batman
19+
mail: dick.grayson@wgd.com

docker/auth-idp/saml/authsources.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
'example-userpass' => array(
1010
'exampleauth:UserPass',
11-
'saml.user1:user1pass' => array(
11+
'frodo.baggins:showmerings' => array(
1212
'uid' => array('1'),
1313
'eduPersonAffiliation' => array('group1'),
14-
'email' => 'user1@saml.mage.test',
14+
'email' => 'frodo.baggins@saml.mage.test',
1515
),
16-
'saml.user2:user2pass' => array(
16+
'samwise.gamgee:bringyourgardner' => array(
1717
'uid' => array('2'),
1818
'eduPersonAffiliation' => array('group2'),
19-
'email' => 'user2@saml.mage.test',
19+
'email' => 'samwise.gamgee@saml.mage.test',
2020
),
2121
),
2222

docs/admin/auth.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ Click the _Login_ link on the left pane. The root user name and password for
4646
the LDAP server are `cn=admin,dc=wgd,dc=com` and `i found something`,
4747
respectively.
4848

49-
You can then use the phpLDAPAdmin UI to setup a simple group structure.
49+
The docker/docker-compose.yml file starts up the mage-idp-ldap container with the ldapseed.ldiff file.
50+
This file will seed the ldap server with a batman and robin user under the Field Agents org. Below are steps to do the same
51+
using the phpLDAPAdmin UI should any more users need to be generated.
52+
53+
Using the phpLDAPAdmin UI to setup a simple group structure.
5054
1. Click the _dc=wgd,dc=com_ root node in the tree view on the left of the page.
5155
1. In the main pane, click _Create a child entry_.
5256
1. Select the _Generic: Posix Group_ template.
@@ -79,9 +83,7 @@ authentication in MAGE. This assumes you're running a MAGE server on
7983
http://localhost:4242.
8084
1. Open the MAGE web app in your browser.
8185
1. Click the gear icon in the top right to load the _Admin_ page.
82-
1. Click the _Settings_ tab in the vertical tab strip on the left.
83-
1. The _Authentication_ tab in the main pane should already be active. Click
84-
the tab if not.
86+
1. Click the _Security_ tab in the vertical tab strip on the left.
8587
1. Click the _New Authentication_ button.
8688
1. Enter a title for the authentication IDP, e.g. `Test LDAP`.
8789
1. Click the _Next_ button.
@@ -126,3 +128,50 @@ http://localhost:4242.
126128
1. The app may prompt for a device UID if your settings dictate. Enter the
127129
device UID.
128130
1. You are now authenticated with your LDAP account.
131+
132+
## SAML
133+
You can setup MAGE to authenticate users with an SAML server. For development
134+
testing, the [`auth-idp`](../docker/auth-idp/docker-compose.yml) Compose file
135+
uses the [kristophjunge/test-saml-idp](https://github.com/kristophjunge/docker-test-saml-idp)
136+
Start the `mage-idp-saml` SAML
137+
service with the following commands.
138+
```bash
139+
cd docker/auth-idp
140+
docker compose up -d mage-idp-saml
141+
```
142+
143+
The docker compose file is set to seed a few users with the .saml/authsources.php file. This
144+
file is mounted under volumes in the docker compose. Once it is spun up, you are ready to
145+
configure your saml authentication provider.
146+
147+
1. Open the MAGE web app in your browser.
148+
1. Click the gear icon in the top right to load the _Admin_ page.
149+
1. Click the _Security_ tab in the vertical tab strip on the left.
150+
1. Click the _New Authentication_ button.
151+
1. Enter a title for the authentication IDP, e.g. `Test SAML`.
152+
1. Click the _Next_ button.
153+
1. Fill in the _Settings_ fields as follows.
154+
| | |
155+
| ---: | ---|
156+
| **_Idepntity Provider (idP)_** |
157+
| _Entry Point_ | `http://localhost:8080/simplesaml/saml2/idp/SSOService.php` |
158+
| _Issuer_ | `http://localhost:4242` |
159+
| _Redirect Host_ | `http://localhost:4242/auth/saml/callback` |
160+
| **_Security_** |
161+
| _idP Public Signing Certificate_ | navigate to http://localhost:8080/simplesaml/saml2/idp/metadata.php. look for the <ds:X509Certificate> tag and copy everything in that tag |
162+
| **_Validation_** |
163+
| **_Issuer_** |
164+
| _idP Issuer_ | `http://localhost:8080/simplesaml/saml2/idp/metadata.php` |
165+
| **_Logout_** |
166+
| _logout URL_ | `http://localhost:8080/simplesaml/saml2/idp/SingleLogoutService.php` |
167+
1. Click the _Next_ button.
168+
1. Adjust the color settings to your preference.
169+
1. Click the _Next_ button.
170+
1. Review the settings and click the _Save_ button.
171+
1. Open a new private browser tab or window and load your MAGE server web app.
172+
1. The sign-in page should display a button labeled _Continue with SAML_
173+
1. Clicking this button will take you to a simple login page where the saml server is running.
174+
1. for Username enter `saml.user1`
175+
1. for Pasword enter `user2pass`
176+
1. Depending on how the login was configured, you will either be redirected through to the application, or
177+
a user will have been created which will require approval from an admin.

service/src/authentication/ldap.js

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ function configure(strategy) {
2323
groupSearchScope: strategy.settings.groupSearchScope,
2424
bindProperty: strategy.settings.bindProperty,
2525
groupDnProperty: strategy.settings.groupDnProperty
26-
}
26+
},
27+
usernameField: 'username',
28+
passwordField: 'password'
2729
},
2830
function (profile, done) {
2931
const username = profile[strategy.settings.profile.id ];
@@ -103,43 +105,42 @@ function initialize(strategy) {
103105
invalidCredentials: `Invalid ${strategy.title} username/password.`
104106
};
105107

106-
app.post(`/auth/${strategy.name}/signin`,
107-
function authenticate(req, res, next) {
108-
passport.authenticate(strategy.name, authenticationOptions, function (err, user, info = {}) {
109-
if (err) return next(err);
110-
111-
if (!user) {
112-
return res.status(401).send(info.message);
113-
}
114-
115-
if (!user.active) {
116-
return res.status(info.status || 401).send('User account is not approved, please contact your MAGE administrator to approve your account.');
117-
}
118-
119-
if (!user.enabled) {
120-
log.warn('Failed user login attempt: User ' + user.username + ' account is disabled.');
121-
return res.status(401).send('Your account has been disabled, please contact a MAGE administrator for assistance.')
122-
}
123-
124-
if (!user.authentication.authenticationConfigurationId) {
125-
log.warn('Failed user login attempt: ' + user.authentication.type + ' is not configured');
126-
return res.status(401).send(user.authentication.type + ' authentication is not configured, please contact a MAGE administrator for assistance.')
127-
}
128-
129-
if (!user.authentication.authenticationConfiguration.enabled) {
130-
log.warn('Failed user login attempt: Authentication ' + user.authentication.authenticationConfiguration.title + ' is disabled.');
131-
return res.status(401).send(user.authentication.authenticationConfiguration.title + ' authentication is disabled, please contact a MAGE administrator for assistance.')
132-
}
133-
134-
tokenService.generateToken(user._id.toString(), TokenAssertion.Authorized, 60 * 5)
135-
.then(token => {
136-
res.json({
137-
user: userTransformer.transform(req.user, { path: req.getRoot() }),
138-
token: token
139-
});
140-
}).catch(err => next(err));
141-
})(req, res, next);
142-
}
108+
app.post(`/auth/${strategy.name}/signin`, function authenticate(req, res, next) {
109+
passport.authenticate(strategy.name, authenticationOptions, function (err, user, info = {}) {
110+
if (err) return next(err);
111+
112+
if (!user) {
113+
return res.status(401).send(info.message);
114+
}
115+
116+
if (!user.active) {
117+
return res.status(info.status || 401).send('User account is not approved, please contact your MAGE administrator to approve your account.');
118+
}
119+
120+
if (!user.enabled) {
121+
log.warn('Failed user login attempt: User ' + user.username + ' account is disabled.');
122+
return res.status(401).send('Your account has been disabled, please contact a MAGE administrator for assistance.')
123+
}
124+
125+
if (!user.authentication.authenticationConfigurationId) {
126+
log.warn('Failed user login attempt: ' + user.authentication.type + ' is not configured');
127+
return res.status(401).send(user.authentication.type + ' authentication is not configured, please contact a MAGE administrator for assistance.')
128+
}
129+
130+
if (!user.authentication.authenticationConfiguration.enabled) {
131+
log.warn('Failed user login attempt: Authentication ' + user.authentication.authenticationConfiguration.title + ' is disabled.');
132+
return res.status(401).send(user.authentication.authenticationConfiguration.title + ' authentication is disabled, please contact a MAGE administrator for assistance.')
133+
}
134+
135+
tokenService.generateToken(user._id.toString(), TokenAssertion.Authorized, 60 * 5)
136+
.then(token => {
137+
res.json({
138+
user: userTransformer.transform(req.user, { path: req.getRoot() }),
139+
token: token
140+
});
141+
}).catch(err => next(err));
142+
})(req, res, next);
143+
}
143144
);
144145
};
145146

web-app/src/app/user/user.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class UserService {
6969
}
7070

7171
ldapSignin(username: string, password: string): Observable<any> {
72-
return this.httpClient.post<any>('/api/ldap/signin', {
72+
return this.httpClient.post<any>('/auth/ldap/signin', {
7373
username,
7474
password,
7575
appVersion: 'Web Client'

0 commit comments

Comments
 (0)