Angular JS + Node JS + Passport + Spring OAuth2 Authentication/Authorization - angularjs

I am new to PassportJS and AngularJS and I have a doubt about how to proceed with this authorization.
I have Spring REST API Secured by Oauth2, but I have to send together user credentials like this:
[http://localhost:8080/myapp/oauth/token]
grant_type=password&username=email&password=password&client_id=09e749d8309f4044&client_secret=189309492722aa5a&scope=read
In client my application I use passport and I want to authorize/authenticate my users, how can I create a Stratagy for this ?
I will send here my server config and my security Lib.
Server.js
var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync(__dirname + '/cert/privatekey.pem').toString();
var certificate = fs.readFileSync(__dirname + '/cert/certificate.pem').toString();
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var config = require('./config.js');
var passport = require('passport');
var security = require('./lib/security');
var xsrf = require('./lib/xsrf');
var protectJSON = require('./lib/protectJSON');
require('express-namespace');
var app = express();
var secureServer = https.createServer(credentials, app);
var server = http.createServer(app);
// Serve up the favicon
app.use(express.favicon(config.server.distFolder + '/favicon.ico'));
// First looks for a static file: index.html, css, images, etc.
app.use(config.server.staticUrl, express.compress());
app.use(config.server.staticUrl, express['static'](config.server.distFolder));
app.use(config.server.staticUrl, function(req, res, next) {
res.send(404); // If we get here then the request for a static file is invalid
});
app.use(protectJSON);
app.use(express.logger()); // Log requests to the console
app.use(express.bodyParser()); // Extract the data from the body of the request - this is needed by the LocalStrategy authenticate method
app.use(express.cookieParser(config.server.cookieSecret)); // Hash cookies with this secret
app.use(express.cookieSession()); // Store the session in the (secret) cookie
app.use(passport.initialize()); // Initialize PassportJS
app.use(passport.session()); // Use Passport's session authentication strategy - this stores the logged in user in the session and will now run on any request
app.use(xsrf); // Add XSRF checks to the request
security.initialize(config.oauth.authorize_url, config.oauth.access_token, config.oauth.apiKey, config.oauth.secretKey, config.oauth.scopereq); // Add a Oauth strategy for handling the authentication
app.use(function(req, res, next) {
if ( req.user ) {
console.log('Current User:', req.user.firstName, req.user.lastName);
} else {
console.log('Unauthenticated');
}
next();
});
app.post('/login', security.login);
app.post('/logout', security.logout);
// Retrieve the current user
app.get('/current-user', security.sendCurrentUser);
// Retrieve the current user only if they are authenticated
app.get('/authenticated-user', function(req, res) {
security.authenticationRequired(req, res, function() { security.sendCurrentUser(req, res); });
});
// Retrieve the current user only if they are admin
app.get('/admin-user', function(req, res) {
security.adminRequired(req, res, function() { security.sendCurrentUser(req, res); });
});
// This route deals enables HTML5Mode by forwarding missing files to the index.html
app.all('/*', function(req, res) {
// Just send the index.html for other files to support HTML5Mode
res.sendfile('index.html', { root: config.server.distFolder });
});
// A standard error handler - it picks up any left over errors and returns a nicely formatted server 500 error
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
// Start up the server on the port specified in the config
server.listen(config.server.listenPort, 'localhost', 511, function() {
// // Once the server is listening we automatically open up a browser
var open = require('open');
open('http://localhost:' + config.server.listenPort + '/');
});
console.log('Deengo Business App Server - listening on port: ' + config.server.listenPort);
secureServer.listen(config.server.securePort);
console.log('Deengo Business App Server - listening on secure port: ' + config.server.securePort);
lib/security.js
var express = require('express');
var passport = require('passport');
var app = express();
var BearerStrategy = require('passport-http-bearer').Strategy
var filterUser = function(user) {
if ( user ) {
return {
user : {
id: user._id.$oid,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
admin: user.admin
}
};
} else {
return { user: null };
}
};
var security = {
initialize: function(_authorize_url, _access_token, _apiKey, _secretKey, _scopereq) {
passport.use('deengo-auth', new OAuth2Strategy({
authorizationURL: _authorize_url,
tokenURL: _access_token,
clientID: _apiKey,
clientSecret: _secretKey,
callbackURL: 'http://localhost:3000/oauth/autorize/callback',
scope: _scopereq,
passReqToCallback: true,
skipUserProfile: true
},
function(req, accessToken, refreshToken, profile, done) {
client['headers']['authorization'] = 'bearer ' + req.session.passport.accessToken;
User.findOrCreate({ clientId: clientId }, function(err, user) {
done(err, user);
});
}
));
},
authenticationRequired: function(req, res, next) {
console.log('authRequired');
if (req.isAuthenticated()) {
next();
} else {
res.json(401, filterUser(req.user));
}
},
adminRequired: function(req, res, next) {
console.log('adminRequired');
if (req.user && req.user.admin ) {
next();
} else {
res.json(401, filterUser(req.user));
}
},
sendCurrentUser: function(req, res, next) {
res.json(200, filterUser(req.user));
res.end();
},
login: function(req, res, next) {
console.log(req.body.email);
console.log(req.body.password);
function authenticationFailed(err, user, info){
//if (err) { return next(err); }
/*if (!user) { return res.json(filterUser(user)); }
req.logIn(user, function(err) {
if ( err ) { return next(err); }
return res.json(filterUser(user));
});*/
}
//passport.authenticate("deengo-auth", authenticationFailed)(req, res, next);
return null;
},
logout: function(req, res, next) {
req.logout();
res.send(204);
}
};
module.exports = security;
lib/DeengoStrategy.js
var util = require('util');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var BearerStrategy = require('passport-http-bearer').Strategy;
var rest = require('request');
function DeengoRestStrategy(authorize_url, access_token, apiKey, secretKey, scopereq) {
this.authorize_url = authorize_url;
this.access_token = access_token;
this.apiKey = apiKey;
this.secretKey = secretKey;
this.scopereq = secretKey;
this.baseUrl = 'http://localhost:8080/deengo/api/';
// Call the super constructor - passing in our user verification function
// We use the email field for the username
LocalStrategy.call(this, { usernameField: 'email' }, this.verifyUser.bind(this));
// Serialize the user into a string (id) for storing in the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// Deserialize the user from a string (id) into a user (via a cll to REST)
passport.deserializeUser(this.get.bind(this));
// We want this strategy to have a nice name for use by passport, e.g. app.post('/login', passport.authenticate('deengo'));
this.name = DeengoRestStrategy.name;
}
// DeengoRestStrategy inherits from LocalStrategy
util.inherits(DeengoRestStrategy, LocalStrategy);
DeengoRestStrategy.name = "deengo";
// Query the users collection
DeengoRestStrategy.prototype.query = function(query, done) {
query.accessToken = this.accessToken; // Add the apiKey to the passed in query
var request = rest.get(this.baseUrl, { qs: query, json: {} }, function(err, response, body) {
done(err, body);
});
};
// Get a user by id
DeengoRestStrategy.prototype.get = function(id, done) {
var query = { apiKey: this.apiKey };
var request = rest.get(this.baseUrl + id, { qs: query, json: {} }, function(err, response, body) {
done(err, body);
});
};
// Find a user by their email
DeengoRestStrategy.prototype.findByEmail = function(email, done) {
this.query({ q: JSON.stringify({email: email}) }, function(err, result) {
if ( result && result.length === 1 ) {
return done(err, result[0]);
}
done(err, null);
});
};
// Check whether the user passed in is a valid one
DeengoRestStrategy.prototype.verifyUser = function(email, password, done) {
this.findByEmail(email, function(err, user) {
if (!err && user) {
if (user.password !== password) {
user = null;
}
}
done(err, user);
});
};
module.exports = DeengoRestStrategy;
I do not know if I have to use passport-Bearer or not and how to use-it.
Thanks in advance for any help.
Regards,
Eduardo.

I do not know if I have to use passport-Bearer or not and how to use-it.
No. There are other options, such as:
oauth.io
httpProvider + express middleware
Here is an example of how to use passport:
// Express using passport-local
// This code is adaptation of examples/express3 from https://github.com/jaredhanson/passport-local
// configure Express
app.configure(function() {
// ...
app.use(express.session({
// The domain should start with a dot, as this allows the subdomain.
domain: '.app.local',
secret: 'keyboard cat'
}));
// Enable cors.
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
next();
});
// ...
});
app.get('/account', ensureAuthenticated, function(req, res){
// Return the current user's info
res.json(req.user);
});
References
Express + AngularJS Subdomain login

Related

Response for preflight requests are invalid - passport and react

We are trying to use passportjs for authenticating using ADFS. However, an error is thrown despite adding cors to our requests. Added both the server code and client code. The server code is also available here.
auth0/node-jsonwebtoken#59
Server - Code
'use strict';
// N.B. Encoding problems are being caused by jsonwebtoken
// auth0/node-jsonwebtoken#59
var app = require('express')(),
cookieParser = require('cookie-parser'),
jwt = require('jsonwebtoken'),
passport = require('passport'),
OAuth2Strategy = require('passport-oauth').OAuth2Strategy,
fs = require('fs');
var cors = require('cors');
var https = require('https');
console.warn('Not verifying HTTPS certificates');
https.globalAgent.options.rejectUnauthorized = false;
// Exported from ADFS
var adfsSigningPublicKey = fs.readFileSync('ADFS-Signing.cer','utf8');
var cert = convertCertificate(adfsSigningPublicKey);
function validateAccessToken(accessToken) {
var payload = null;
try {
payload = jwt.verify(accessToken, cert,{algorithms: ["HS256"], ignoreExpiration: true});
}
catch(e) {
console.warn('Dropping unverified accessToken', e);
}
return payload;
}
function convertCertificate (cert) {
//Certificate must be in this specific format or else the function won't accept it
var beginCert = "-----BEGIN CERTIFICATE-----";
var endCert = "-----END CERTIFICATE-----";
cert = cert.replace("\n", "");
cert = cert.replace(beginCert, "");
cert = cert.replace(endCert, "");
var result = beginCert;
while (cert.length > 0) {
if (cert.length > 64) {
result += "\n" + cert.substring(0, 64);
cert = cert.substring(64, cert.length);
}
else {
result += "\n" + cert;
cert = "";
}
}
if (result[result.length ] != "\n")
result += "\n";
result += endCert + "\n";
return result;
}
// Configure passport to integrate with ADFS
var strategy = new OAuth2Strategy({
authorizationURL: 'https://sso.xxx.com/adfs/oauth2/authorize',
tokenURL: 'https://sso.xxx.com/adfs/oauth2/token',
clientID: 'xxxxxxxx-xxxx-xxxx-xxxx-0cxxx4489fa', // This is just a UID I generated and registered
clientSecret: 'shhh-its-a-secret', // This is ignored but required by the OAuth2Strategy
callbackURL: 'http://localhost:3000/getAToken'
},
function(accessToken, refreshToken, profile, done) {
if (refreshToken) {
console.log('Received but ignoring refreshToken (truncated)', refreshToken.substr(0, 25));
} else {
console.log('No refreshToken received');
}
console.log("done ** " + profile);
done(null, profile);
});
strategy.authorizationParams = function(options) {
return {
resource: 'iggggggg' // An identifier corresponding to the RPT
};
};
strategy.userProfile = function(accessToken, done) {
done(null, accessToken);
};
passport.use('provider', strategy);
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
// Configure express app
app.use(cookieParser());
app.use(cors());
app.use(passport.initialize());
// app.options('*', cors());
app.use(function(req, res, next) {
// res.header('Content-type', 'text/plain')
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header('Access-Control-Allow-Methods', 'GET,POST');
//res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
app.get('/login', passport.authenticate('provider'),function(req, res) {
// Beware XSRF...
// res.json({ message: "ok", token: req.user });
});
app.get('/getAToken', passport.authenticate('provider'), function(req, res) {
// Beware XSRF...
console.log("*********************************");
res.cookie('accessToken', req.user);
res.redirect('/');
//res.json({ message: "ok", token: req.user });
});
app.get('/', function (req, res) {
console.log('default is called');
req.user = validateAccessToken(req.cookies['accessToken']);
res.send(
!req.user ? 'Log In' : 'Log Out' +
'
' + JSON.stringify(req.user, null, 2) + '
');
});
// app.get('/logout',cors(), function (req, res) {
// res.clearCookie('accessToken');
// res.redirect('/');
// });
app.listen(3000);
console.log('Express server started on port 3000');
And my client code is below.
const params = {
method: 'GET',
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST",
"Access-Control-Allow-Headers": "Content-type",
"Access-Control-Allow-Credentials": true,
},
withCredentials: true
}
axios('/login', params)
.then(response => {
response.data;
})
.catch(error => {
debugger;
console.log('error');
})`
The error received is below.
Response to preflight request is invalid. Is something wrong with my cors?

Passport Authentication success but does not redirect and gives 500 error

I am learning mean stack by making a social media web app like twitter
But at the time of signup or login i am getting success and a user also was created in database but the page does not redirects and gives error 500
The following is the code
App.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
require('./models/models.js');
var index = require('./routes/index');
var api = require('./routes/api');
var authenticate = require('./routes/authenticate')(passport);
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/chirp-test');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
var initPassport = require('./passport-init');
initPassport(passport);
app.use('/', index);
app.use('/auth', authenticate);
app.use('/api', api);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
authenticate.js
var express = require('express');
var router = express.Router();
module.exports = function(passport){
router.get('/success', function(req, res){
res.send({state: 'success', user: req.user ? req.user : null});
});
router.get('/failure', function(req, res){
res.send({state: 'failure', user: null, message: "Invalid username or password"});
});
//log in
router.post('/login', passport.authenticate('login', {
successRedirect: '/auth/success/',
failureRedirect: '/auth/failure'
}));
//sign up
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
//log out
router.get('/signout', function(req, res) {
req.logout();
res.redirect('/');
});
return router;
}
passport-init.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bCrypt = require('bcrypt-nodejs');
var mongoose = require('mongoose');
var User = mongoose.model('User');
var Post = mongoose.model('Post');
module.exports = function(passport){
passport.serializeUser(function(user, done) {
return done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user){
if(err){
return done(err, false);
}
if(!user){
return done('User not found', false);
}
return done(user, true);
})
});
passport.use('login', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
User.findOne({'username': username}, function(err, user){
if(err){
return done(err, false);
}
if(!user){
return done('Username does not exist ', false);
}
if(!isValidPassword(user, password)){
return done('Incorrect password', false);
}
return done(null, user);
});
}
));
passport.use('signup', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
User.findOne({'username' : username}, function(err, user){
if(err){
return done(err, false);
}
if(user){
return done('Username already taken', false);
}
var newUser = new User();
newUser.username = username;
newUser.password = createHash(password)
newUser.save(function(err, user){
if(err){
return done(err, false);
}
console.log('Successfully signed up User ' + username);
return done(null, newUser);
});
});
})
);
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
};
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
};
};
The error is somewhere in your passport-init.js where you invoke done() with a string as a first argument, e.g. done('User not found', false)
What you want to do instead is throw an actual error:
done(new Error('User not found'), false);
and then handle it later. Once you find the error you can find the reason for redirect to (not) work.

While executing passport.authenticate, displays as unauthorized 404 in get post

File router.js contains the routers that are used.
In the ionic2, providers are made with the post method by giving uri as http://localhost:8080/api/auth/login which gives 400 bad request error in the debugger tools.
I have found that when I removerequireLoginthen the post is working fine.But I needrequireLogin` for authenticating the local login of passport.
router.js
//require the passport strategy from the folder in the project.
var passport = require('passport');
var x = require('./usefile/file');
var requireLogin = passport.authenticate('local',{session: false});
module.exports = function(app){
var auth = express.Router();
app.use('/api/auth', auth);
auth.post('/login', requireLogin, function(req, res){
x.login(req, res)});
}
passport.js
var passport = require('passport');
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var LocalStrategy = require('passport-local').Strategy;
var config = require('./auth');
var User = require('../models/user');
var localOptions = {
usernameField: 'email',
};
var localLogin = new LocalStrategy(localOptions, function (email, password, done) {
User.find(
{ email: email }, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, { error: 'Login failed,Please try again.' });
}
if (!isMatch) {
return done(null, false, { error: 'Login failed, Please try again.' });
}
user.comparePassword(function(password, isMatch){
if(err){
return done(err);
}
if(!isMatch){
return done(null, false, {error:'Login failed, Please try again.'});
}
return done(null, user);
});
});
});
passport.use(localLogin);
Note: My code is not using the requireLogin which is used to authenticate from the passport, So it is showing 400 bad request error.
Please Help.
have you required your local passport file? You seem to be requiring the npm passport module, and not your local file.
You should change the first line of code in router.js to
//require the passport strategy from the folder in the project.
var passport = require('./passport');//<--change this line
var x = require('./usefile/file');
var requireLogin = passport.authenticate('local',{session: false});
module.exports = function(app){
var auth = express.Router();
app.use('/api/auth', auth);
auth.post('/login', requireLogin, function(req, res){
x.login(req, res)});
}
Let me know how that goes.

Cannot POST /api/register in Node Js

I am new at here and I am getting Can not post /api/register error in postman and 404 not found in console, I have checked all the possible question answers. Please assist me as soon as possible.
Thanks in advance.
The auth.controller.js file
var express = require ('express'); //EXPRESS Package
var route = express.Router(); //define our app using express
// var userModel = require('../model/user.model');
// var session = require('express-session');
var bodyParser = require('body-parser');// get body-parser
route.use(bodyParser.json()); // for parsing application/json
route.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
/**
*
* Register user
*/
route.post('/api/register', function (req, res) {
console.log(req.body);//res.sendStatus(200);
// userModel.create(req.body).then( function () {
// res.sendStatus(200);
// }).catch( function (err) {
// res.status(400).send(err);
// });
});
/**
*
* Login user
*/
route.post('/api/login', function (req, res) {
// userModel.authenticate(req.body.email, req.body.password).then( function () {
// res.sendStatus(200);
// }).catch( function (err) {
// res.status(400).send(err);
// });
});
module.exports = route;
=========================================================================
The server.js File
var express = require ('express'); //EXPRESS Package
var app = express(); //define our app using express
var cors = require('cors');
var session = require('express-session');
var bodyParser = require('body-parser');// get body-parser
// var morgan = require('morgan'); //use to see requests
// var assert = require('assert');
// var path = require('path');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// app.use(cors());
/**
* Header Control
*/
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH");
res.header('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version');
next();
} );
//routes
app.use('/api/register', require('./controllers/auth.controller'));
app.use('/api/login', require('./controllers/auth.controller'));
// app.use('/api/users', require('./controllers/users.controller'));
// app.get('/api', function (req, res) {
// res.send('/api/login');
// } );
// start server
var server = app.listen(8001, 'localhost', function () {
console.log('Server listening at http://' + server.address().address + ':' + server.address().port);
});
// module.exports = app;
When you use
app.use('/api/register', require('./controllers/auth.controller'));
Your application routes everything that comes to /api/register into require('./controllers/auth.controller'). Then require('./controllers/auth.controller') checks the remainder of the url for /api/register or /api/login, routes the request to the respective middleware if your router gets a match.
In other words, you need to post to /api/register/api/register in order to reach your desired middleware.
For a quick solution:
You should delete
app.use('/api/register', require('./controllers/auth.controller'));
app.use('/api/login', require('./controllers/auth.controller'));
and replace it with:
app.use('/', require('./controllers/auth.controller'));
For a better one:
You should delete
app.use('/api/register', require('./controllers/auth.controller'));
app.use('/api/login', require('./controllers/auth.controller'));
and replace it with:
app.use('/api', require('./controllers/auth.controller'));
in your app.js and also in your auth.controller.js you should replace:
route.post('/api/register', function (req, res) {
console.log(req.body);//res.sendStatus(200);
// userModel.create(req.body).then( function () {
// res.sendStatus(200);
// }).catch( function (err) {
// res.status(400).send(err);
// });
});
/**
*
* Login user
*/
route.post('/api/login', function (req, res) {
// userModel.authenticate(req.body.email, req.body.password).then( function () {
// res.sendStatus(200);
// }).catch( function (err) {
// res.status(400).send(err);
// });
});
with:
route.post('/register', function (req, res) {
console.log(req.body);//res.sendStatus(200);
// userModel.create(req.body).then( function () {
// res.sendStatus(200);
// }).catch( function (err) {
// res.status(400).send(err);
// });
});
/**
*
* Login user
*/
route.post('/login', function (req, res) {
// userModel.authenticate(req.body.email, req.body.password).then( function () {
// res.sendStatus(200);
// }).catch( function (err) {
// res.status(400).send(err);
// });
});

LDAP Authentication with NodeJS, Express, and Passport-ldapauth

I"m having trouble authenticating to an Active Directory Server with the tools/applications mentioned in the title.
I'm using a test AD environment found here
Here are the relevant code snippets, if anyone has any suggestions I would really appreciate it.
Currently, the error i'm getting is "invalid username/password". I'm not sure if this is the bindDn account/pw or the one the user enters in the form. According to the passport-ldapauth project it's:
invalidCredentials flash message for InvalidCredentialsError
NoSuchObjectError, and
/no such user/i LDAP errors (default: 'Invalid username/password')
Thanks in advance.
CLIENT - auth.service.js
...
login: function(user, callback) {
var cb = callback || angular.noop;
var deferred = $q.defer();
$http.post('/auth/ldap', {
email: user.email,
password: user.password
}).
success(function(data) {
$cookieStore.put('token', data.token);
currentUser = User.get();
deferred.resolve(data);
return cb();
}).
error(function(err) {
this.logout();
deferred.reject(err);
return cb(err);
}.bind(this));
return deferred.promise;
},
...
SERVER index.js
'use strict';
var express = require('express');
var passport = require('passport');
var auth = require('../auth.service');
var router = express.Router();
router.post('/', function(req, res, next) {
passport.authenticate('ldapauth', function (err, user, info) {
var error = err || info;
if (error) return res.json(401, error);
if (!user) return res.json(404, {message: 'Something went wrong, please try again.'});
var token = auth.signToken(user._id, user.role);
res.json({token: token});
})(req, res, next)
});
module.exports = router;
SERVER passport.js
var passport = require('passport');
var LdapStrategy = require('passport-ldapauth').Strategy;
exports.setup = function (User, config) {
passport.use(new LdapStrategy({
usernameField: 'email',
passwordField: 'password',
server: {
url: 'ldap://ldap.forumsys.com:389',
bindDn: "cn=read-only-admin,dc=example,dc=com",
bindCredentials: "password",
searchBase: 'ou=mathematicians,dc=example,dc=com',
searchFilter: 'uid={{username}}'
}
},
function (user, done) {
return done(null, user);
}
));
};
The problem is with the ou=mathematicians in the search base. There is the following mention in the comments on that web page:
The issue you are seeing is due to the fact that “uid=riemann” is a member of “ou=mathemeticians”, but does not reside under that ou. His membership in that ou is established by a uniqueMember attribute on “ou=mathemeticians”.
This should work (tried it even with ldapauth-fork which passport-ldapauth uses):
var opts = {
server: {
"url": "ldap://ldap.forumsys.com:389",
"adminDn": "cn=read-only-admin,dc=example,dc=com",
"adminPassword": "password",
"searchBase": "dc=example,dc=com",
"searchFilter": "(uid={{username}})",
}
};
For whose still lose your way, here is my code snippet in Typescript.
Server Side
import * as express from 'express'
import * as bodyParser from 'body-parser'
import * as cors from 'cors'
import * as passport from 'passport'
import * as ldapstrategy from 'passport-ldapauth'
// connect to LDAP server
const OPTS: ldapstrategy.Options = {
server: {
url: "ldap://ldap.forumsys.com",
bindDN: "cn=read-only-admin,dc=example,dc=com",
bindCredentials: 'password',
searchBase: "dc=example,dc=com",
searchFilter: "(uid={{username}})"
}
}
passport.use(new ldapstrategy(OPTS))
// instantiate the server
const app = express()
// parse the request data automatically
app.use(bodyParser.json())
// allow cross origin resource sharing
app.use(cors())
// inject LDAP connection to express server
app.use(passport.initialize())
// listen to port defined
const port = process.env.PORT || 8085
app.listen(port, (): void => {
console.log(`Listening on port ${port}`)
})
app.post('/login', (req: express.Request, res: express.Response, next: express.NextFunction): void | Response => {
passport.authenticate('ldapauth', (err, user, info): void => {
var error = err || info
if (error)
res.send({
status: 500,
data: error
})
if (!user)
res.send({
status: 404,
data: "User Not Found"
})
else
res.send({
status: 200,
data: user
})
})(req, res, next)
})
Client Side
Your code looks correct, but the error you're getting leads me to believe you really don't have the correct username/password supplied! Are you sure you're testing with the right credentials?
As a sidenote -- if you're looking for a simpler way to do this for a big project, and don't mind spending some money, Stormpath's API service does this sort of thing for you: it basically syncs your AD / LDAP users into it's API service so you can work with them via a REST API (it's much simpler).
There are two libraries you can use to work with it:
express-stormpath
passport-stormpath
Both are pretty simple / nice to use.
this code me
phpLDAPadmin express.js and passport-ldapauth
var express = require('express'),
passport = require('passport'),
LdapStrategy = require('passport-ldapauth');
const OPTS = {
server: {
url: 'ldap://localhost:389',
bindDN: 'cn=admin,dc=ramhlocal,dc=com',
bindCredentials: 'password',
searchBase: 'dc=ramhlocal,dc=com',
searchFilter: '(uid={{username}})'
}
};
var app = express();
passport.use(new LdapStrategy(OPTS));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(passport.initialize());
app.post('/login', function (req, res, next){
passport.authenticate('ldapauth', {session: false}, function(err, user, info) {
var error = err || info
console.log(user);
if (error)
res.send({
status: 500,
data: error
})
if (! user) {
res.send({
status: 404,
data: "User Not Found"
})
}
res.send({
status: 200,
data: user
})
})(req, res,next)
})
app.listen(8080);
enter image description here

Resources