зеркало из https://github.com/mozilla/MozDef.git
Merge pull request #419 from mozilla/meteor_login
Added logic to allow the option of using meteor accounts for sign-in …
This commit is contained in:
Коммит
f31f048869
|
@ -192,16 +192,18 @@ Marvel plugin
|
|||
|
||||
`Marvel`_ is a monitoring plugin developed by Elasticsearch (the company).
|
||||
|
||||
WARNING: this plugin is NOT open source. At the time of writing, Marvel is free for development but you have to get a license for production.
|
||||
WARNING: this plugin is NOT open source. At the time of writing, Marvel is free for 30 days.
|
||||
After which you can apply for a free basic license to continue using it for it's key monitoring features.
|
||||
|
||||
To install Marvel, on each of your elasticsearch node, from the Elasticsearch home directory::
|
||||
|
||||
sudo bin/plugin -i elasticsearch/marvel/latest
|
||||
sudo bin/plugin install license
|
||||
sudo bin/plugin install marvel-agent
|
||||
sudo service elasticsearch restart
|
||||
|
||||
You should now be able to access to Marvel at http://any-server-in-cluster:9200/_plugin/marvel
|
||||
|
||||
.. _Marvel: http://www.elasticsearch.org/overview/marvel/
|
||||
.. _Marvel: https://www.elastic.co/guide/en/marvel/current/introduction.html
|
||||
|
||||
Web and Workers nodes
|
||||
---------------------
|
||||
|
@ -228,9 +230,9 @@ On APT-based systems::
|
|||
Then::
|
||||
|
||||
su - mozdef
|
||||
wget http://python.org/ftp/python/2.7.6/Python-2.7.6.tgz
|
||||
tar xvzf Python-2.7.6.tgz
|
||||
cd Python-2.7.6
|
||||
wget https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz
|
||||
tar xvzf Python-2.7.11.tgz
|
||||
cd Python-2.7.11
|
||||
./configure --prefix=/opt/mozdef/python2.7 --enable-shared
|
||||
make
|
||||
make install
|
||||
|
@ -247,7 +249,7 @@ Then::
|
|||
source mozdef/bin/activate
|
||||
pip install -r MozDef/requirements.txt
|
||||
|
||||
At this point when you launch python, It should tell you that you're using Python 2.7.6.
|
||||
At this point when you launch python, It should tell you that you're using Python 2.7.11.
|
||||
|
||||
Whenever you launch a python script from now on, you should have your mozdef virtualenv actived and your LD_LIBRARY_PATH env variable should include /opt/mozdef/python2.7/lib/
|
||||
|
||||
|
@ -256,14 +258,21 @@ RabbitMQ
|
|||
|
||||
`RabbitMQ`_ is used on workers to have queues of events waiting to be inserted into the Elasticsearch cluster (storage).
|
||||
|
||||
RabbitMQ does provide a zero-dependency RPM that you can find for RedHat/CentOS here::
|
||||
https://github.com/rabbitmq/erlang-rpm
|
||||
|
||||
For Debian/Ubuntu based distros you would need to install erlang separately.
|
||||
|
||||
To install it, first make sure you enabled `EPEL repos`_. Then you need to install an Erlang environment.
|
||||
|
||||
If you prefer to install all the dependencies on a Red Hat based system you can do the following::
|
||||
On Yum-based systems::
|
||||
|
||||
sudo yum install erlang
|
||||
|
||||
You can then install the rabbitmq server::
|
||||
|
||||
sudo rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
|
||||
sudo rpm --import https://www.rabbitmq.com/rabbitmq-signing-key-public.asc
|
||||
sudo yum install rabbitmq-server
|
||||
|
||||
To start rabbitmq at startup::
|
||||
|
@ -307,34 +316,52 @@ For meteor, in a terminal::
|
|||
|
||||
curl https://install.meteor.com/ | sh
|
||||
|
||||
wget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz
|
||||
tar xvzf node-v0.10.26.tar.gz
|
||||
cd node-v0.10.26
|
||||
wget https://nodejs.org/dist/v4.7.0/node-v4.7.0.tar.gz
|
||||
tar xvzf node-v4.7.0.tar.gz
|
||||
cd node-v4.7.0
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Make sure you have meteorite/mrt (run as root/admin)::
|
||||
|
||||
npm install -g meteorite
|
||||
|
||||
Then from the meteor subdirectory of this git repository (/opt/mozdef/MozDef/meteor) run::
|
||||
|
||||
mrt add iron-router
|
||||
mrt add accounts-persona
|
||||
meteor add iron-router
|
||||
|
||||
You may want to edit the app/lib/settings.js file to properly point to your elastic search server::
|
||||
If you wish to use meteor as the authentication handler you'll also need to install the Accounts-Password pkg::
|
||||
meteor add accounts-password
|
||||
|
||||
elasticsearch={
|
||||
address:"http://servername:9200/",
|
||||
healthurl:"_cluster/health",
|
||||
docstatsurl:"_stats/docs"
|
||||
}
|
||||
You may want to edit the app/lib/settings.js file to properly configure the URLs and Authentication
|
||||
The default setting will use Meteor Accounts, but you can just as easily install an external provider like Github, Google, Facebook or your own OIDC::
|
||||
|
||||
mozdef = {
|
||||
rootURL: "localhost",
|
||||
port: "443",
|
||||
rootAPI: "https://localhost:8444",
|
||||
kibanaURL: "https://localhost:9443/app/kibana#",
|
||||
enableBlockIP: true,
|
||||
enableClientAccountCreation: true,
|
||||
authenticationType: "meteor-password"
|
||||
}
|
||||
|
||||
or for an OIDC implementation that passes a header to the nginx reverse proxy (for example using OpenResty with Lua and Auth0)::
|
||||
|
||||
mozdef = {
|
||||
rootURL: "localhost",
|
||||
port: "443",
|
||||
rootAPI: "https://localhost:8444",
|
||||
kibanaURL: "https://localhost:9443/app/kibana#",
|
||||
enableBlockIP: true,
|
||||
enableClientAccountCreation: false,
|
||||
authenticationType: "OIDC"
|
||||
}
|
||||
|
||||
Then start meteor with::
|
||||
|
||||
meteor
|
||||
|
||||
.. _meteor: https://guide.meteor.com/
|
||||
.. _meteor-accounts: https://guide.meteor.com/accounts.html
|
||||
|
||||
|
||||
Node
|
||||
******
|
||||
|
@ -344,9 +371,9 @@ Alternatively you can run the meteor UI in 'deployment' mode using a native node
|
|||
First install node::
|
||||
|
||||
yum install bzip2 gcc gcc-c++ sqlite sqlite-devel
|
||||
wget http://nodejs.org/dist/v0.10.25/node-v0.10.25.tar.gz
|
||||
tar xvfz node-v0.10.25.tar.gz
|
||||
cd node-v0.10.25
|
||||
wget https://nodejs.org/dist/v4.7.0/node-v4.7.0.tar.gz
|
||||
tar xvfz node-v4.7.0.tar.gz
|
||||
cd node-v4.7.0
|
||||
python configure
|
||||
make
|
||||
make install
|
||||
|
@ -363,7 +390,7 @@ You can then deploy the meteor UI for mozdef as necessary::
|
|||
|
||||
This will create a 'bundle' directory with the entire UI code below that directory.
|
||||
|
||||
You will need to update the settings.js file to match your servername/port::
|
||||
If you didn't update the settings.js before bundling the meteor installation, you will need to update the settings.js file to match your servername/port::
|
||||
|
||||
vim bundle/programs/server/app/app/lib/settings.js
|
||||
|
||||
|
@ -374,7 +401,8 @@ the fibers node module::
|
|||
rm -rf fibers
|
||||
sudo npm install fibers@1.0.1
|
||||
|
||||
Then run the mozdef UI via node::
|
||||
There are systemd unit files available in the systemd directory of the public repo you can use to start meteor using node.
|
||||
If you aren't using systemd, then run the mozdef UI via node manually::
|
||||
|
||||
export MONGO_URL=mongodb://mongoservername:3002/meteor
|
||||
export ROOT_URL=http://meteorUIservername/
|
||||
|
@ -400,11 +428,11 @@ On apt-get based system::
|
|||
|
||||
If you don't have this package in your repos, before installing create `/etc/yum.repos.d/nginx.repo` with the following content::
|
||||
|
||||
[nginx]
|
||||
name=nginx repo
|
||||
baseurl=http://nginx.org/packages/centos/6/$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
[nginx]
|
||||
name=nginx repo
|
||||
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
|
||||
.. _nginx: http://nginx.org/
|
||||
|
||||
|
@ -413,9 +441,9 @@ UWSGI
|
|||
|
||||
We use `uwsgi`_ to interface python and nginx::
|
||||
|
||||
wget http://projects.unbit.it/downloads/uwsgi-2.0.2.tar.gz
|
||||
tar zxvf uwsgi-2.0.2.tar.gz
|
||||
cd uwsgi-2.0.2
|
||||
wget https://projects.unbit.it/downloads/uwsgi-2.0.12.tar.gz
|
||||
tar zxvf uwsgi-2.0.12.tar.gz
|
||||
cd uwsgi-2.0.12
|
||||
~/python2.7/bin/python uwsgiconfig.py --build
|
||||
~/python2.7/bin/python uwsgiconfig.py --plugin plugins/python core
|
||||
cp python_plugin.so ~/envs/mozdef/bin/
|
||||
|
@ -442,16 +470,16 @@ We use `uwsgi`_ to interface python and nginx::
|
|||
sudo vim /etc/nginx/nginx.conf
|
||||
sudo service nginx restart
|
||||
|
||||
.. _uwsgi: http://projects.unbit.it/uwsgi/
|
||||
.. _uwsgi: https://uwsgi-docs.readthedocs.io/en/latest/
|
||||
|
||||
Kibana
|
||||
******
|
||||
|
||||
`Kibana`_ is a webapp to visualize and search your Elasticsearch cluster data::
|
||||
|
||||
wget https://download.elasticsearch.org/kibana/kibana/kibana-3.0.0milestone5.tar.gz
|
||||
tar xvzf kibana-3.0.0milestone5.tar.gz
|
||||
mv kibana-3.0.0milestone5 kibana
|
||||
wget https://download.elastic.co/kibana/kibana/kibana-4.6.2-linux-x86_64.tar.gz
|
||||
tar xvzf kibana-4.6.2-linux-x86_64.tar.gz
|
||||
ln -s kibana-4.6.2 kibana
|
||||
# configure /etc/nginx/nginx.conf to target this folder
|
||||
sudo service nginx reload
|
||||
|
||||
|
@ -460,11 +488,13 @@ To initialize elasticsearch indices and load some sample data::
|
|||
cd examples/es-docs/
|
||||
python inject.py
|
||||
|
||||
.. _Kibana: http://www.elasticsearch.org/overview/kibana
|
||||
.. _Kibana: https://www.elastic.co/products/kibana
|
||||
|
||||
Start Services
|
||||
**************
|
||||
|
||||
TO DO: Add in services like supervisord, and refer to systemd files.
|
||||
|
||||
Start the following services
|
||||
|
||||
cd ~/MozDef/mq
|
||||
|
@ -541,21 +571,22 @@ Manual Installation
|
|||
6. Installing Kibana ::
|
||||
|
||||
$ cd /tmp/
|
||||
$ curl -L https://download.elasticsearch.org/kibana/kibana/kibana-3.1.0.tar.gz | tar -C /opt -xz
|
||||
$ /bin/ln -s /opt/kibana-3.1.0 /opt/kibana
|
||||
$ curl -L https://download.elastic.co/kibana/kibana/kibana-4.6.2-linux-x86_64.tar.gz | tar -C /opt -xz
|
||||
$ /bin/ln -s /opt/kibana-4.6.2 /opt/kibana
|
||||
$ cp $MOZDEF_PATH/examples/kibana/dashboards/alert.js /opt/kibana/app/dashboards/alert.js
|
||||
$ cp $MOZDEF_PATH/examples/kibana/dashboards/event.js /opt/kibana/app/dashboards/event.js
|
||||
|
||||
7. Installing Elasticsearch ::
|
||||
|
||||
$ wget https://gist.githubusercontent.com/yashmehrotra/3209a7e2c696c2ac5110/raw/9161ffb32ee79d48f4bce224f8710ac8c7e85922/ElasticSearch.sh
|
||||
# You can download any version of ELasticSearch
|
||||
$ ./ElasticSearch.sh 1.6.0
|
||||
For Red Hat based:
|
||||
$ wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/rpm/elasticsearch/2.4.5/elasticsearch-2.4.5.rpm
|
||||
For Debian based:
|
||||
$ wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.4.5/elasticsearch-2.4.5.deb
|
||||
# You can download and install any version of ELasticSearch > 2.x and < 5.x
|
||||
|
||||
8. Setting up Meteor ::
|
||||
|
||||
$ curl -L https://install.meteor.com/ | /bin/sh
|
||||
$ npm install -g meteorite
|
||||
$ cd $MOZDEF_PATH/meteor
|
||||
$ meteor
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ Jeff Bryner jbryner@mozilla.com
|
|||
Anthony Verez averez@mozilla.com
|
||||
Yash Mehrotra yashmehrotra95@gmail.com
|
||||
Avijit Gupta 526avijit@gmail.com
|
||||
Alicia Smith asmith@mozilla.com
|
||||
*/
|
||||
|
||||
if (Meteor.isClient) {
|
||||
|
@ -25,10 +26,10 @@ if (Meteor.isClient) {
|
|||
Session.set('attackerlimit','10');
|
||||
getAllPlugins();
|
||||
|
||||
//assumes connection to an nginx/apache front end
|
||||
//serving up an site handling authentication set via
|
||||
//server side header
|
||||
Meteor.loginViaHeader();
|
||||
// Sends us to register our login handler
|
||||
// and then to the login function of choice
|
||||
// based on how enableClientAccountCreation was set at deployment.
|
||||
Meteor.login();
|
||||
|
||||
//see if we have a myo armband
|
||||
try{
|
||||
|
@ -369,7 +370,27 @@ if (Meteor.isClient) {
|
|||
}
|
||||
});
|
||||
|
||||
//sample login function
|
||||
// login abstraction
|
||||
Meteor.login = function(callback) {
|
||||
var authenticationType = mozdef.authenticationType;
|
||||
switch(authenticationType){
|
||||
case 'meteor-password':
|
||||
Meteor.loginViaPassword(callback);
|
||||
break;
|
||||
case 'oidc':
|
||||
Meteor.loginViaHeader(callback);
|
||||
break;
|
||||
default:
|
||||
// non-breaking default of header
|
||||
// todo: evaluate defaulting to meteor-password
|
||||
Meteor.loginViaHeader(callback);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//assumes connection to an nginx/apache front end
|
||||
//serving up an site handling authentication set via
|
||||
//server side header
|
||||
Meteor.loginViaHeader = function(callback) {
|
||||
//create a login request to pass to loginHandler
|
||||
var loginRequest = {};
|
||||
|
@ -380,4 +401,8 @@ if (Meteor.isClient) {
|
|||
});
|
||||
};
|
||||
|
||||
Meteor.loginViaPassword = function(callback) {
|
||||
// noop - allow meteor to pass through
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ Contributors:
|
|||
Jeff Bryner jbryner@mozilla.com
|
||||
Anthony Verez averez@mozilla.com
|
||||
Brandon Myers bmyers@mozilla.com
|
||||
Alicia Smith asmith@mozilla.com
|
||||
*/
|
||||
|
||||
//configuration settings
|
||||
|
@ -18,6 +19,7 @@ mozdef = {
|
|||
rootAPI: "https://localhost:8444",
|
||||
kibanaURL: "https://localhost:9443/app/kibana#",
|
||||
enableBlockIP: true,
|
||||
enableClientAccountCreation: false
|
||||
enableClientAccountCreation: true,
|
||||
authenticationType: "meteor-password"
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@ Copyright (c) 2014 Mozilla Corporation
|
|||
Contributors:
|
||||
Jeff Bryner jbryner@mozilla.com
|
||||
Anthony Verez averez@mozilla.com
|
||||
Alicia Smith asmith@mozilla.com
|
||||
*/
|
||||
|
||||
if (Meteor.isServer) {
|
||||
|
||||
Meteor.startup(function () {
|
||||
// Since we only connect to localhost or to ourselves, adding a hack to bypass cert validation
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED="0";
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
console.log("MozDef starting")
|
||||
|
||||
//important to set this so persona can validate the source request
|
||||
|
@ -27,82 +28,180 @@ if (Meteor.isServer) {
|
|||
//Pull in settings.js entries into a collection
|
||||
//so the client gets dynamic content
|
||||
mozdefsettings.remove({});
|
||||
mozdefsettings.insert({ key:'rootURL',
|
||||
value : mozdef.rootURL + ':' + mozdef.port });
|
||||
mozdefsettings.insert({ key:'rootAPI',
|
||||
value : mozdef.rootAPI });
|
||||
mozdefsettings.insert({ key:'kibanaURL',
|
||||
value : mozdef.kibanaURL });
|
||||
mozdefsettings.insert({ key:'enableBlockIP',
|
||||
value : mozdef.enableBlockIP });
|
||||
mozdefsettings.insert({
|
||||
key: 'rootURL',
|
||||
value: mozdef.rootURL + ':' + mozdef.port
|
||||
});
|
||||
mozdefsettings.insert({
|
||||
key: 'rootAPI',
|
||||
value: mozdef.rootAPI
|
||||
});
|
||||
mozdefsettings.insert({
|
||||
key: 'kibanaURL',
|
||||
value: mozdef.kibanaURL
|
||||
});
|
||||
mozdefsettings.insert({
|
||||
key: 'enableBlockIP',
|
||||
value: mozdef.enableBlockIP
|
||||
});
|
||||
|
||||
//allow local account creation?
|
||||
//http://docs.meteor.com/#/full/accounts_config
|
||||
mozdefsettings.insert({ key:'enableClientAccountCreation',
|
||||
value : mozdef.enableClientAccountCreation || false});
|
||||
|
||||
|
||||
Accounts.registerLoginHandler("headerLogin",function(loginRequest) {
|
||||
//there are multiple login handlers in meteor.
|
||||
//a login request go through all these handlers to find it's login hander
|
||||
//so in our login handler, we only consider login requests which are via a header
|
||||
var self=this;
|
||||
var sessionData = self.connection || (self._session ? self._session.sessionData : self._sessionData);
|
||||
var session = Meteor.server.sessions[self.connection.id];
|
||||
//ideally we would use a header unique to the installation like HTTP_OIDC_CLAIM_ID_TOKEN_EMAIL
|
||||
//however sockJS whitelists only certain headers
|
||||
// https://github.com/sockjs/sockjs-node/blob/8b03b3b1e7be14ee5746847f517029cb3ce30ca7/src/transport.coffee#L132
|
||||
// choose one that is passed on and set it in your http server config:
|
||||
var headerName='via';
|
||||
|
||||
console.log('connection headers',this.connection.httpHeaders);
|
||||
console.log('target header:',this.connection.httpHeaders[headerName]);
|
||||
//our authentication logic
|
||||
//check for user email header
|
||||
if(this.connection.httpHeaders[headerName] == undefined) {
|
||||
console.log('refused login request due to missing http header')
|
||||
return null;
|
||||
}
|
||||
console.log('handling login request',loginRequest);
|
||||
|
||||
//grab the email from the header
|
||||
var userEmail = this.connection.httpHeaders[headerName];
|
||||
|
||||
//we create a user if needed, and get the userId
|
||||
var userId = null;
|
||||
var user = Meteor.users.findOne({profile:{email:userEmail}});
|
||||
if(!user) {
|
||||
console.log('creating user:',userEmail)
|
||||
userId = Meteor.users.insert({
|
||||
profile: { email: userEmail},
|
||||
username: userEmail,
|
||||
emails: [{address:userEmail , "verified": true}],
|
||||
createdAt: new Date()
|
||||
});
|
||||
} else {
|
||||
userId = user._id;
|
||||
}
|
||||
|
||||
//generate login tokens
|
||||
var stampedToken = Accounts._generateStampedLoginToken();
|
||||
var hashStampedToken = Accounts._hashStampedToken(stampedToken);
|
||||
//console.log(stampedToken,hashStampedToken);
|
||||
//send loggedin user's user id
|
||||
return {
|
||||
userId: userId
|
||||
}
|
||||
var enableClientAccountCreation = !!(mozdef.enableClientAccountCreation || false);
|
||||
Accounts._options.enableClientAccountCreation = enableClientAccountCreation;
|
||||
mozdefsettings.insert({
|
||||
key: 'enableClientAccountCreation',
|
||||
value: enableClientAccountCreation
|
||||
});
|
||||
|
||||
// newer meteor uses a key of forbidClientAccountCreation, so
|
||||
// we negate the enableClientAccountCreation mozdef setting
|
||||
Accounts._options.forbidClientAccountCreation = !enableClientAccountCreation;
|
||||
mozdefsettings.insert({
|
||||
key: 'forbidClientAccountCreation',
|
||||
value: !!!enableClientAccountCreation
|
||||
});
|
||||
|
||||
registerLoginMethod();
|
||||
|
||||
//update veris if missing:
|
||||
console.log("checking the veris framework reference enumeration");
|
||||
console.log('tags: ' + veris.find().count());
|
||||
if (veris.find().count()==0) {
|
||||
if (veris.find().count() == 0) {
|
||||
console.log("updating the veris collection");
|
||||
var verisFile = Assets.getText("veris.dotformat.txt");
|
||||
var verisObject = verisFile.split("\n");
|
||||
verisObject.forEach(function(verisItem) {
|
||||
veris.insert({tag: verisItem});
|
||||
verisObject.forEach(function (verisItem) {
|
||||
veris.insert({ tag: verisItem });
|
||||
});
|
||||
}
|
||||
|
||||
}); //end startup
|
||||
}); //end startup
|
||||
} //end is server
|
||||
|
||||
|
||||
function registerLoginMethod() {
|
||||
// Setup a single login method to allow
|
||||
var authenticationType = mozdef.authenticationType;
|
||||
console.log("Authentication Type: ", authenticationType);
|
||||
switch (authenticationType) {
|
||||
case 'meteor-password':
|
||||
registerLoginViaPassword();
|
||||
break;
|
||||
case 'oidc':
|
||||
registerLoginViaHeader();
|
||||
break;
|
||||
default:
|
||||
// non-breaking default of header
|
||||
// todo: evaluate defaulting to meteor-password
|
||||
registerLoginViaHeader();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function registerLoginViaPassword() {
|
||||
console.log("Setting up Password Authentication");
|
||||
// We need to attach the users email address to the user.profile
|
||||
Accounts.onCreateUser(function (options, user) {
|
||||
if (user.emails.count <= 0) {
|
||||
console.log("No user emails")
|
||||
return user;
|
||||
}
|
||||
|
||||
var email = user.emails[0].address;
|
||||
if (typeof (email) === "undefined") {
|
||||
console.log("User Email address not defined.")
|
||||
return user;
|
||||
}
|
||||
|
||||
if (typeof (user.profile) === "undefined") {
|
||||
// user has no profile - this is the usual case
|
||||
user.profile = {
|
||||
"email": email
|
||||
};
|
||||
} else {
|
||||
// overwrite any email that may be attached
|
||||
// to the current user profile. this should
|
||||
// not happen as we are currently creating
|
||||
// the user.
|
||||
user.profile['email'] = email;
|
||||
}
|
||||
|
||||
// set any other profile information here.
|
||||
|
||||
return user
|
||||
});
|
||||
}
|
||||
|
||||
function registerLoginViaHeader() {
|
||||
Accounts.registerLoginHandler("headerLogin", function (loginRequest) {
|
||||
//there are multiple login handlers in meteor.
|
||||
//a login request go through all these handlers to find it's login hander
|
||||
//so in our login handler, we only consider login requests which are via a header
|
||||
var self = this;
|
||||
var sessionData = self.connection || (self._session ? self._session.sessionData : self._sessionData);
|
||||
|
||||
// TODO: Figure out where the bug is (probably sessionData as it is never used)
|
||||
// There is either a bug here, assigning the session, or a bug when assigning sessionData. One of these can not ever happen.
|
||||
var session = Meteor.server.sessions[self.connection.id];
|
||||
//ideally we would use a header unique to the installation like HTTP_OIDC_CLAIM_ID_TOKEN_EMAIL
|
||||
//however sockJS whitelists only certain headers
|
||||
// https://github.com/sockjs/sockjs-node/blob/8b03b3b1e7be14ee5746847f517029cb3ce30ca7/src/transport.coffee#L132
|
||||
// choose one that is passed on and set it in your http server config:
|
||||
var headerName = 'via';
|
||||
|
||||
// Logging httpHeaders is possibly leaking sensitive data
|
||||
console.log('connection headers', this.connection.httpHeaders);
|
||||
|
||||
//grab the email from the header
|
||||
var userEmail = this.connection.httpHeaders[headerName];
|
||||
|
||||
//our authentication logic
|
||||
//check for user email header
|
||||
if (userEmail == undefined) {
|
||||
console.log('refused login request due to missing http header')
|
||||
// throw
|
||||
return new {
|
||||
error: handleError("SSO Login failure: email not found")
|
||||
};
|
||||
}
|
||||
|
||||
console.log('target header:', userEmail);
|
||||
console.log('handling login request', loginRequest);
|
||||
|
||||
//we create a user if needed, and get the userId
|
||||
var userId = null;
|
||||
var user = Meteor.users.findOne({ profile: { email: userEmail } });
|
||||
if (user) {
|
||||
userId = user._id;
|
||||
} else {
|
||||
console.log('creating user:', userEmail)
|
||||
userId = Meteor.users.insert({
|
||||
profile: { email: userEmail },
|
||||
username: userEmail,
|
||||
emails: [{ address: userEmail, "verified": true }],
|
||||
createdAt: new Date()
|
||||
});
|
||||
}
|
||||
|
||||
//generate login tokens
|
||||
var stampedToken = Accounts._generateStampedLoginToken();
|
||||
var hashStampedToken = Accounts._hashStampedToken(stampedToken);
|
||||
//console.log(stampedToken,hashStampedToken);
|
||||
//send loggedin user's user id
|
||||
return {
|
||||
userId: userId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleError(msg) {
|
||||
const error = new Meteor.Error(
|
||||
403,
|
||||
Accounts._options.ambiguousErrorMessages
|
||||
? "Login failure. Please check your login credentials."
|
||||
: msg
|
||||
);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче