jaredhanson / passport-http Goto Github PK
View Code? Open in Web Editor NEWHTTP Basic and Digest authentication strategies for Passport and Node.js.
License: MIT License
HTTP Basic and Digest authentication strategies for Passport and Node.js.
License: MIT License
There is no example for DigestStrategy's nonce validation callback right now, which makes it difficult to understand how complete the module's implementation is and if we're less secure if we don't supply such a callback. Also, we don't know what we should actually be doing in that callback, because the only example just returns true.
lib/passport-http/strategies/digest.js
we see that if a validation callback wasn't provided, success is implied, so it appears that some extra verification can be added by this?params.opaque
now will become params.nonce
later or if they're two different concepts.nonce()
does seem to generate something unique, so I speculate that we might be safe against replays without a custom validation callback, but it's just an educated guess.I've tried everything from expressjs and connect's logout and logOut and it's just not working.
Hi There,
I have been using Passport for numerous years now. In the current platform that I run, I use Passport's local strategy for authentication. This has been working fine for several months.
Today, I added a new Basic Strategy authentication system to the mix. This is completely separate from the standard Local Strategy that already exists.
My code is as follows:
var basic = require('passport-http').BasicStrategy;
passport.use(new basic({},
function(username, password, done) {
console.log('here we are');
}
));
and the following is part of a different function
if(path == '/the/correct/path'){
console.log('OUTSIDE AUTH');
passport.authenticate('basic', { session: false }, function(req, res){
console.log('INSIDE AUTH');
});
}
When I make a request to /the/correct/path
, OUTSIDE AUTH
gets printed properly. However, I then expect here we are
from the passport.use()
function to get printed, which it never. I'm really frustrated, as I have no idea how this is supposed to work...
I have tried accessing this via browser, via curl calls (as per the example), using older & newer versions of the module, and using the DigestStrategy instead of the BasicStrategy. Any advice on what to do would be greatly appreciated... Also I am NOT using express if that makes a difference at all...
Best, and thanks either way,
Sami
Ran into an issue when testing my site with the Digest strategy and using an empty username. It seems that if you put in an empty string for the username then the passport module will return a 400 instead of a 401. From the digest auth spec it appears an empty username is valid and 401 should be returned. This change may seems minor but the 400 really screws up the auth caching in browsers and other HTTP stacks. In Chrome, after the 400, your credentials are now cached and it won't prompt for another user/pass until the cache is cleared (browser restart).
I suggest removing the check for a valid username in digest.js
digest.js:111 - digest:113
/*
if (!creds.username) {
return this.fail(400);
}
*/
Thanks
Maybe I'm missing something: I'm trying to implement a service using different 'layers of authentication', to do so I'd like to specify 3 different BasicStrategy
. As I understood from an old issue (jaredhanson/passport#50) this is possible for LocalStrategy
, but I've been unsuccessfull to do the same for BasicStrategy
, since the constructor doesn't allow custom names.
Is there any reason for this asymmetric behaviour between the strategies?
I even tried to instantiate the strategy, then assign a custom name and use it like this:
var adminStrat = new BasicStrategy(.....);
passport.use('admin-strat', adminStrat);
exports.isAdmin = passport.authenticate('admin-strat', { session: false });
The first PR (#38) were proposed in 2014 and have not yet been applied.
Can we expect a fix?
I can see that the DigestStrategy already supports md5-sess
But then why in the response header it is not returned
According to the rfc2617#3.2.1 it would be assumed as md5 always
algorithm
A string indicating a pair of algorithms used to produce the digest
and a checksum. If this is not present it is assumed to be "MD5".
If the algorithm is not understood, the challenge should be ignored
(and a different one used, if there is more than one).
Since this strategy support both md5 and md5-sess, should the response header include both of them
Digest realm="", algorithm="MD5,MD5-sess", nonce="", qop=""
Really rather out of date now. This means that passport-http currently picks up passport#0.1.18.
Suggest we update this to be current.
Hi,
Like other strategies it will be great if you can support 'passReqToCallback' option. I can send in a pull request if you would like.
I try to use:
app.get('/login'
passport.authenticate('digest', { session: false,failureRedirect: '/login',
successRedirect: '/' })
);
web browser throws 302 statuscode when I visit the url.
18 months since @jaredhanson committed or merged pull requests. Should we fork to integrate fixes? Does anyone want to volunteer to do this?
hi there, I just occurred a problem now,
( express or restify ) seems could not triggered request stream event anymore
after set a " asynchronous verification "
here is the simple demo which I test.
var express = require('express'),
app = express(),
passport = require('passport'),
BasicStrategy = require('passport-http').BasicStrategy;
var users = [
{ id: 1, username: 'bob', password: 'secret', email: '[email protected]' }
, { id: 2, username: 'joe', password: 'birthday', email: '[email protected]' }
];
function findByUsername(username, fn) {
for (var i = 0, len = users.length; i < len; i++) {
var user = users[i];
if (user.username === username) {
return fn(null, user);
}
}
return fn(null, null);
}
passport.use(new BasicStrategy(
function(username, password, done) {
process.nextTick(function () {
findByUsername(username, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (user.password != password) { return done(null, false); }
return done(null, user);
})
});
}));
app.configure(function() {
app.use(express.logger());
app.use(passport.initialize());
app.use(app.router);
});
app.post('/upload',
passport.authenticate('basic', { session: false }),
function(req, res, next) {
var dataLength = 0;
req.on('data', function(chunk) {
console.log('loading');
dataLength += chunk.length;
}).on('end', function() {
console.log('load end');
console.log('contentLength: %s', req.headers['content-length']);
console.log('dataLength: : %s', dataLength);
res.send(200);
});
});
app.listen(8080, function() {
console.log('server is running');
});
in normal way, the console should print like:
server is running
loading
loading
loading
load end
contentLength: 355968
dataLength: : 355968
(content-length should match with the real data-length which we got)
(but in this simple code, most time can not triggered stream event, or data-length would be loss)
but if use asynchronous verification, console won't print any info from the stream event,
even it would get fail if we try to using req.pipe() to upload the data to amazon s3 by know.
and without asynchronous verification, I can not get account info from mongodb.
is there any way to verify account by asynchronous way and make sure request stream work fine ?
ps: What I Upload is a mp3 file which about 300kbs, I had try this issue with jpg image too.
BasicStrategy requires non-empty user-id and password. But according to the specifications (http://tools.ietf.org/html/rfc1945#section-11.1), both the user-id and the password can be empty, only the ":" is required.
My use case is using Passport to authenticate a public OAuth2 client. Public client don't have a client secret. So they should not provide an empty password when authenticating using HTTP Basic Authentication.
Some APIs (including mine!) use HTTP Basic Auth, but read the username as an API token and ignore the password field. Notably, Stripe does this. It would be great to have the ability to pass a passwordRequired
option, which defaults to true to preserve backwards compatability, but that can be set to false to disable the requirement.
From this:
var userid = credentials[0];
var password = credentials[1];
if (!userid || !password) {
return this.fail(this._challenge());
}
To this:
var userid = credentials[0];
var password = credentials[1];
if (!userid || (options.passwordRequired && !password)) {
return this.fail(this._challenge());
}
I'm happy to submit a pull request
Given this project appears to be abandoned, is there any good alternatives or are we able to get more contributors added so we can merge the many pull requests (often fixing the same bugs)
Steps to reproduce:
/api/login
),authenticate()
) that outputs user information from request.user
(from session), e.g.: /api/me
.Expected result:
I am not sure if this is a bug of BasicStrategy or a "feature" of Passport.js, but I think users should be forcefully logged out when trying to double-login with incorrect credentials.
Colons are legal characters in passwords. Because of the way the BASIC strategy splits the BASIC username:password header, passwords containing a colon character fail. Per the following code from basic.js:
var scheme = parts[0]
, credentials = new Buffer(parts[1], 'base64').toString().split(':');
if (!/Basic/i.test(scheme)) { return this.fail(this._challenge()); }
if (credentials.length < 2) { return this.fail(400); }
var userid = credentials[0];
var password = credentials[1];
you can see that a split(':') on "myusername:my:password" will result in 3 parts instead of the expected 2. Better to use something like:
.split(':').slice(1).join(':')
or a regexp to get the password. Not sure that I can work up a patch before the new year, but reporting the issue now.
It's generally considered best practice to use
!==
instead of
!=
Would it be better to use
!==
in this line?
https://github.com/jaredhanson/passport-http/blob/master/examples/basic/app.js#L39
I am using basic authentication for authenticating client credentials in Oauth2orize. In my tests I am using a browser based test-client to do the testing. If the credentials are wrong I get the basic form for user and password being opened to submit username and password.
I don't want that...I just want it to return 401. Is this a problem for browser based client only or is this for all clients? If its for all clients How do I avoid it and just return 401.
How to login from HTML form if I'm using passport-http not passport-local since I'm using http is b/c it can be used by postman but now I don't know how to send login request using html form
The html form works fine when I'm using passport-local
but since I change to passport-http
it does not work
This probably isn't a bug, but I want everything on the server to be password protected with basic HTTP authentication. This includes files under the express.static() folder. In the example code provided, none of the static files trigger the passport authentication. How would one do this?
Hello,
This is not really an issue but is there a way to mix both Basic HTTP and Local passport strategies? The reason is that I would like to use Basic for easy testing with supertest (using request(app).auth()), and some clients which are totally restful otherwise a simple login form using the Local POST strategy.
In essence, I want to apply a middleware routine using app.use('*', ensureAuthenticated, ...), where ensureAuthenticated checks if the session exists and is authenticated or the http credentials are provided).
The other examples of mixing twitter, oath and other passport strategies does not really apply since they are all based on mapping disctinct routes whereas stateless auth like basic and digest authenticate at every request.
Thanks for any advice,
Nicolas
Is there any module in node to make a client example for the digest strategy?!
Is the session options still applicable in basic auth strategy as I can't see anything in the code that uses this option setting. If not then the documentation is out of date. Thanks.
Once I am logged in, the req.user is no longer included in any following requests. I using the express-session and the passport session in that order. All I see in the cookie is the connect-sid. I am using the default Memory Store using passport-http. I see that it tries to store the user object session which disappears in any requests following the login.
I am using express 4.X.
"body-parser": "^1.15.1",
"connect-redis": "3.0.2",
"cookie-parser": "^1.4.3",
"express": "4.13.4",
"express-handlebars": "3.0.0",
"express-logger": "0.0.3",
"express-session": "^1.13.0",
"express-static": "^1.1.0",
"fs": "0.0.1-security",
"https": "^1.0.0",
"passport": "0.3.2",
"passport-http": "0.3.0"
I'm trying to implement two different basic strategies, with two different sets of correct tokens. Right now it looks like the basic strategy hard codes the name to basic
, it would be nice if you could set this via options that way you could have multiple basic strategies with different names.
If there is a better way to go about handling this I'd love to hear about it.
I am trying to use basicauth for ajax cors but the user and the password in the node server passport-http come undefined. What I am missing in here?
app.use(passport.initialize());
app.use(allowCrossDomain);
app.use(app.router);
where allowCrossDomain is for allowing cors requests
$.ajax
({
type: "POST",
url: "https://kelvin-new:8000/admin",
dataType: 'json',
crossDomain: true,
async: false,
username: $("#login#username").val(),
password: $("#login#password").val(),
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic " + btoa($("#login#username").val() + ":" + $("#login#password").val()))
},
data: '{ "comment" }',
withCredentials: true,
done: function (res){
alert('Thanks for your comment!');
},
error: function(error) {
alert(error.statusText);
}
});
In the last https://github.com/jaredhanson/passport-http/commit/f7a163f5d47c96c0be74d9af30c1c0b376cc57d9 commit you deleted some example files. I would like to know in which repository are the multi authentication example files now?
The docs here and on the npm page do not mention how to plug passport into the express middleware pipeline.
This is missing: app.use(passport.initialize());
The Basic stragegy implements the passReqToCallback option, but support for this is missing in the Digest strategy.
Perhaps both callbacks, secret and validate, should honour this option.
At the moment you are not taking info in basic auth callback. So extra information about authenticated client cannot be passed to req.authInfo object.
I changed code as follows.
this._verify(userid, password, function(err, user, info) {
if (err) { return self.error(err); }
if (!user) { return self.fail(self._challenge()); }
self.success(user, info);
});
I am sure others would also benefit if you change code as above.
Mounting an app at a non-root endpoint fails on the uri check because passport-http is only checking the relative uri as seen by the express app, not by the uri as seen by the client.
e.g.
authApp = require('../modules/auth');
app.use('/auth', authApp);
// ../module/auth.js
app.get('/digest', passport.authenticate 'digest');
Seems to always yield 400.
Hello,
I am unable to apply a DigestStrategy
to a route defined in a express' Router
.
Here's the following snippet. Note the variable use_router
.
var handler = function(req, res) {
res.json({"hello": "world"});
};
if (use_router) {
var router = express.Router();
router.get('/', passport.authenticate('digest', {session: false}), handler);
app.use("/hello", router);
} else {
app.get('/hello', passport.authenticate('digest', {session: false}), handler);
}
I expected to received {"hello": "world"}
if I GET
on /hello
the right username (any value) and password ("password"
).
curl -v --user user:password --digest http://localhost:8888/hello
It does when use_router
is false
, BUT it does not when use_router
is true
.
I would expect aaplying a DigestStrategy
to a route registered in a router to work, but it appears it does not.
Used versions:
In the Digest constructor the 1st function passes in the username, which is where you validate the user exists and then pass back the decrypted password. In the 2nd function, you can validate nonces to avoid replay attacks, but the only parameter passed in, beside the done
function, is the params
object containing the nonce, cnonce, nc, and opaque values.
I'm not sure how we're supposed to determine which user we're dealing within the nonce validation function. I assume the functions are asynchronous, so theoretically if more than one user is authenticating at the same time, I can't assume that the functions will be synchronously called for the same user and save off the user in a static variable somewhere.
Am I missing something? Thanks.
Since userid and password are read as index 0 and 1 of credentials.split(':') the remaining part of the password after ':' is discarded.
There is insufficient documentation to get a working example.
Using the snippet from the README leads to the following error:
/srv/www/routes/v1.js:8
passport.use(new BasicStrategy(
^
ReferenceError: BasicStrategy is not defined
at Object. (/srv/www/routes/v1.js:8:18)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
at Module.require (internal/modules/cjs/loader.js:636:17)
at require (internal/modules/cjs/helpers.js:20:18)
at Object. (/srv/www/server.js:11:12)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:741:12)
at startup (internal/bootstrap/node.js:285:19)
This is strange:
passport.authenticate('basic', function(err, user, info) {
console.log("info is: " + util.inspect(info));
}
Maybe info isn't being passed because it outputs: 'Basic realm="Users"'
and when I change info param to anything else if fails silently.
I created a basic authentication example with Express and when I create a Authentication Basic header with {session: false} it still prompts my web browser with a dialog asking for username and password.
server.js
var app = express();
app.use(express.static(__dirname + '/public')); // starting static fileserver
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(passport.initialize());
app.get('/v1/test',
passport.authenticate('basic', {session: false}),
function(req, res) {
res.send('yup. worked.');
});
I can include more code but this seems to really be all that is required at the moment because I cannot even get to my passport.use(new BasicStrategy....) code because my browser is prompting me for username and password.
So the issue is...the code above creates Basic auth for my server. When I run the code and curl: curl -D- -X GET -H "Authorization: Basic am9lOmpvZ" http://localhost:5000/v1/test
I receive 401 Unauthorized
but the header should authorize me.
Hi,
any way to send custom error codes? Something like
passport.use(new BasicStrategy(
function(userid, password, done) {
User.findOne({ username: userid }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false,401); }
if (!user.verifyPassword(password)) { return done(null, false,403); }
return done(null, user);
});
}
));
so for example
Any clue?
Thank you
This is a great library, and there are many awesome PRs waiting to be merged. You obviously need some help to take this library forward, and it seems from discussions in the issues that many want to help.
Don't let this package die, it's heavily used, and so good!
Please nominate one or two people to help maintain this? You could maybe choose those with the most PRs, as they would be most familiar with your code base.
Please let us know whether you like/hate this idea?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.