Handle SSO over multiple subdomains
parent
e21f865631
commit
606ddc7308
|
@ -1,32 +1,41 @@
|
|||
|
||||
### Level of verbosity for logs
|
||||
# Level of verbosity for logs
|
||||
logs_level: info
|
||||
|
||||
### Configuration of your LDAP
|
||||
# Configuration of LDAP
|
||||
ldap:
|
||||
url: ldap://ldap
|
||||
base_dn: ou=users,dc=example,dc=com
|
||||
user: cn=admin,dc=example,dc=com
|
||||
password: password
|
||||
|
||||
### Configuration of session cookies
|
||||
|
||||
# Configuration of session cookies
|
||||
#
|
||||
# _secret_ the secret to encrypt session cookies
|
||||
# _expiration_ the time before cookies expire
|
||||
# _domain_ the domain to protect.
|
||||
# Note: the authenticator must also be in that domain. If empty, the cookie
|
||||
# is restricted to the subdomain of the issuer.
|
||||
session:
|
||||
secret: unsecure_secret
|
||||
expiration: 3600000
|
||||
domain: example.com
|
||||
|
||||
### The directory where the DB files will be saved
|
||||
|
||||
# The directory where the DB files will be saved
|
||||
store_directory: /var/lib/auth-server/store
|
||||
|
||||
|
||||
### Notifications are sent to users when they require a password reset, a u2f
|
||||
### registration or a TOTP registration.
|
||||
### Use only one available configuration: filesystem, gmail
|
||||
# Notifications are sent to users when they require a password reset, a u2f
|
||||
# registration or a TOTP registration.
|
||||
# Use only one available configuration: filesystem, gmail
|
||||
notifier:
|
||||
### For testing purpose, notifications can be sent in a file
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
filesystem:
|
||||
filename: /var/lib/auth-server/notifications/notification.txt
|
||||
|
||||
### Use your gmail account to send the notifications. You can use an app password.
|
||||
# Use your gmail account to send the notifications. You can use an app password.
|
||||
# gmail:
|
||||
# username: user@example.com
|
||||
# password: yourpassword
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
<title>Home page</title>
|
||||
</head>
|
||||
<body>
|
||||
You need to <a href="/authentication/login?redirect=/">log in</a> to access the <a href="/secret.html">secret</a>!<br/><br/>
|
||||
You can also log off by visiting the following <a href="/authentication/logout?redirect=/">link</a>.
|
||||
You need to <a href="https://auth.test.local:8080/authentication/login?redirect=https://secret.test.local:8080/">log in</a> to access the <a href="/secret.html">secret</a>!<br/><br/>
|
||||
But you can also access it from another <a href="https://secret1.test.local:8080/secret.html">domain</a> or still <a href="https://secret2.test.local:8080/secret.html">another one</a>.<br/><br/>
|
||||
You can also log off by visiting the following <a href="https://auth.test.local:8080/authentication/logout?redirect=https://secret.test.local:8080/">link</a>.
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -24,9 +24,7 @@ events {
|
|||
http {
|
||||
server {
|
||||
listen 443 ssl;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
server_name 127.0.0.1 localhost;
|
||||
server_name auth.test.local localhost;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate /etc/ssl/server.crt;
|
||||
|
@ -34,7 +32,7 @@ http {
|
|||
|
||||
error_page 401 = @error401;
|
||||
location @error401 {
|
||||
return 302 https://localhost:8080/authentication/login?redirect=$request_uri;
|
||||
return 302 https://auth.test.local:8080/authentication/login?redirect=$scheme://$http_host$request_uri;
|
||||
}
|
||||
|
||||
location /authentication/ {
|
||||
|
@ -56,6 +54,30 @@ http {
|
|||
location /authentication/css/ {
|
||||
proxy_pass http://auth/css/;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
server_name secret1.test.local secret2.test.local secret.test.local localhost;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate /etc/ssl/server.crt;
|
||||
ssl_certificate_key /etc/ssl/server.key;
|
||||
|
||||
error_page 401 = @error401;
|
||||
location @error401 {
|
||||
return 302 https://auth.test.local:8080/authentication/login?redirect=$scheme://$http_host$request_uri;
|
||||
}
|
||||
|
||||
location /authentication/verify {
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
||||
proxy_pass http://auth/authentication/verify;
|
||||
}
|
||||
|
||||
location = /secret.html {
|
||||
auth_request /authentication/verify;
|
||||
|
@ -69,3 +91,4 @@ http {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ var u2f = require('authdog');
|
|||
var nodemailer = require('nodemailer');
|
||||
var nedb = require('nedb');
|
||||
var YAML = require('yamljs');
|
||||
var session = require('express-session');
|
||||
|
||||
var config_path = process.argv[2];
|
||||
if(!config_path) {
|
||||
|
@ -27,6 +28,7 @@ var config = {
|
|||
ldap_users_dn: yaml_config.ldap.base_dn,
|
||||
ldap_user: yaml_config.ldap.user,
|
||||
ldap_password: yaml_config.ldap.password,
|
||||
session_domain: yaml_config.session.domain,
|
||||
session_secret: yaml_config.session.secret,
|
||||
session_max_age: yaml_config.session.expiration || 3600000, // in ms
|
||||
store_directory: yaml_config.store_directory,
|
||||
|
@ -48,5 +50,6 @@ deps.u2f = u2f;
|
|||
deps.nedb = nedb;
|
||||
deps.nodemailer = nodemailer;
|
||||
deps.ldap = ldap;
|
||||
deps.session = session;
|
||||
|
||||
server.run(config, ldap_client, deps);
|
||||
|
|
|
@ -35,7 +35,7 @@ function sign_request(req, res) {
|
|||
var u2f = req.app.get('u2f');
|
||||
var meta = doc.meta;
|
||||
var appid = u2f_common.extract_app_id(req);
|
||||
logger.info('U2F sign_request: Start authentication');
|
||||
logger.info('U2F sign_request: Start authentication to app %s', appid);
|
||||
return u2f.startAuthentication(appid, [meta])
|
||||
})
|
||||
.then(function(authRequest) {
|
||||
|
|
|
@ -25,7 +25,7 @@ function register_request(req, res) {
|
|||
var appid = u2f_common.extract_app_id(req);
|
||||
|
||||
logger.debug('U2F register_request: headers=%s', JSON.stringify(req.headers));
|
||||
logger.info('U2F register_request: Starting registration');
|
||||
logger.info('U2F register_request: Starting registration of app %s', appid);
|
||||
u2f.startRegistration(appid, [])
|
||||
.then(function(registrationRequest) {
|
||||
logger.info('U2F register_request: Sending back registration request');
|
||||
|
|
|
@ -7,7 +7,6 @@ var express = require('express');
|
|||
var bodyParser = require('body-parser');
|
||||
var speakeasy = require('speakeasy');
|
||||
var path = require('path');
|
||||
var session = require('express-session');
|
||||
var winston = require('winston');
|
||||
var UserDataStore = require('./user_data_store');
|
||||
var Notifier = require('./notifier');
|
||||
|
@ -28,13 +27,14 @@ function run(config, ldap_client, deps, fn) {
|
|||
app.use(bodyParser.json());
|
||||
app.set('trust proxy', 1); // trust first proxy
|
||||
|
||||
app.use(session({
|
||||
app.use(deps.session({
|
||||
secret: config.session_secret,
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
cookie: {
|
||||
secure: false,
|
||||
maxAge: config.session_max_age
|
||||
maxAge: config.session_max_age,
|
||||
domain: config.session_domain
|
||||
},
|
||||
}));
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ var speakeasy = require('speakeasy');
|
|||
var sinon = require('sinon');
|
||||
var tmp = require('tmp');
|
||||
var nedb = require('nedb');
|
||||
var session = require('express-session');
|
||||
|
||||
var PORT = 8050;
|
||||
var BASE_URL = 'http://localhost:' + PORT;
|
||||
|
@ -88,6 +89,7 @@ describe('test data persistence', function() {
|
|||
deps.u2f = u2f;
|
||||
deps.nedb = nedb;
|
||||
deps.nodemailer = nodemailer;
|
||||
deps.session = session;
|
||||
|
||||
var j1 = request.jar();
|
||||
var j2 = request.jar();
|
||||
|
|
|
@ -7,6 +7,7 @@ var assert = require('assert');
|
|||
var speakeasy = require('speakeasy');
|
||||
var sinon = require('sinon');
|
||||
var MockDate = require('mockdate');
|
||||
var session = require('express-session');
|
||||
|
||||
var PORT = 8090;
|
||||
var BASE_URL = 'http://localhost:' + PORT;
|
||||
|
@ -89,6 +90,7 @@ describe('test the server', function() {
|
|||
deps.nedb = nedb;
|
||||
deps.nodemailer = nodemailer;
|
||||
deps.ldap = ldap;
|
||||
deps.session = session;
|
||||
|
||||
_server = server.run(config, ldap_client, deps, function() {
|
||||
done();
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
var sinon = require('sinon');
|
||||
var server = require('../../src/lib/server');
|
||||
var assert = require('assert');
|
||||
|
||||
describe('test server configuration', function() {
|
||||
it('should set cookie scope to domain set in the config', function() {
|
||||
var config = {};
|
||||
config.session_domain = 'example.com';
|
||||
config.notifier = {
|
||||
gmail: {
|
||||
user: 'user@example.com',
|
||||
pass: 'password'
|
||||
}
|
||||
}
|
||||
|
||||
transporter = {};
|
||||
transporter.sendMail = sinon.stub().yields();
|
||||
|
||||
var nodemailer = {};
|
||||
nodemailer.createTransport = sinon.spy(function() {
|
||||
return transporter;
|
||||
});
|
||||
|
||||
var deps = {};
|
||||
deps.nedb = require('nedb');
|
||||
deps.nodemailer = nodemailer;
|
||||
deps.session = sinon.spy(function() {
|
||||
return function(req, res, next) { next(); };
|
||||
});
|
||||
|
||||
server.run(config, undefined, deps);
|
||||
|
||||
assert(deps.session.calledOnce);
|
||||
assert.equal(deps.session.getCall(0).args[0].cookie.domain, 'example.com');
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue