You need to figure out the hashing algorithm used and modify the scripts they have in the templates, using the Auth0 documentation too, to get it correct. You can find code for the algorithm in the aspnet-identity-pw project.
Here's a sample Login database action script for Auth0 that works with an ASP.NET Core Identity 2.0 database stored in Azure SQL Database:
function login (username, password, callback) {
var Connection = require('[email protected]').Connection;
var Request = require('[email protected]').Request;
var TYPES = require('[email protected]').TYPES;
var connection = new Connection({
userName: configuration.db_username + '@' + configuration.db_server,
password: configuration.db_password,
server: configuration.db_server, //'dbserver.database.windows.net',
options: {
database: configuration.db_database,
encrypt: true
}
});
connection.on('debug', function(text) {
// if you have connection issues, uncomment this to get more detailed info
//console.log(text);
}).on('errorMessage', function(text) {
// this will show any errors when connecting to the SQL database or with the SQL statements
//console.log(JSON.stringify(text));
});
connection.on('connect', function (err) {
if (err) {
console.log('error: ' + JSON.stringify(err));
return callback(err);
}
getMembershipUser(username, function(err, user) {
if (err) {
return callback(err); // this will return a 500
}
if (!user.profile) {
return callback(); // this will return a 401
}
validatePassword(password, user.password.hash, function(err, isValid) {
if (!isValid) {
return callback(); // unauthorized
}
callback(null, user.profile);
});
});
});
// Membership Provider implementation used with ASP.NET Core Identity database
/**
* getMembershipUser
*
* This function gets a username or email and returns a user info, password hashes and salt
*
* @usernameOrEamil {[string]} the username or email, the method will do a query
* on both with an OR
* @callback {[Function]} first argument will be the Error if any, and second
* argument will be a user object
*/
function getMembershipUser(usernameOrEmail, callback) {
var user = {};
var query =
'SELECT Id, UserName, Email, PasswordHash, SecurityStamp from AspNetUsers ' +
'WHERE UserName = @UserName';
var getMembershipQuery = new Request(query);
getMembershipQuery.addParameter('UserName', TYPES.VarChar, usernameOrEmail);
getMembershipQuery.on('row', function (fields) {
user.profile = {};
user.password = {};
for(var f in fields) {
var item = fields[f];
if (item.metadata.colName === 'Id') {
user.profile.user_id = item.value;
} else if (item.metadata.colName === 'UserName') {
user.profile.nickname = item.value;
} else if (item.metadata.colName ==='Email') {
user.profile.email = item.value;
} else if (item.metadata.colName ==='PasswordHash') {
user.password.hash = item.value;
}
}
//console.log('User: ' + JSON.stringify(user));
callback(null, user);
});
connection.execSql(getMembershipQuery);
}
/**
* validatePassword
*
* This function gets the password entered by the user, and the original password
* hash and salt from database and performs an HMAC SHA256 hash.
*
* @password {[string]} the password entered by the user
* @originalHash {[string]} the original password hashed from the database
* (including the salt).
* @return {[bool]} true if password validates
*/
function validatePassword(password, originalHash, callback) {
aspnet_identity_pw.validatePassword(password, originalHash, function(result, isValid) {
console.log('Is Password Valid: ' + isValid);
callback(null, isValid);
});
}
var aspnet_identity_pw = {
validatePassword: function(password, hashedPassword, callback) {
// Original Source:
// https://github.com/Syncbak-Git/aspnet-identity-pw/blob/master/lib/aspnet-identity-pw.js
// https://www.npmjs.com/package/aspnet-identity-pw
// There were some slight modifications to make it run well in Auth0
var done = false;
var error = null;
var result = null;
if(!hashedPassword) {
if(callback) {
callback(null, false);
}
return false;
}
if(!password) {
error = new Error("Password is required.");
if(callback) {
callback(error);
return;
}
throw error;
}
var src = new Buffer(hashedPassword, 'base64');
if(src.length !== 49 || src[0] !== 0) {
return false;
}
var salt = new Buffer(16);
src.copy(salt, 0, 1, 17);
var bytes = new Buffer(32);
src.copy(bytes, 0, 17, 49);
var hashed = crypto.pbkdf2Sync(password, salt, 1000, 32, 'sha1');
result = true;
for(var i = 0; i < 32; i++) {
if(bytes[i] !== hashed[i]) {
result = false;
break;
}
}
done = true;
if(callback) {
callback(null, result);
}
if(!callback) {
throw 'callback required!';
}
}
};
}
This took what seemed like forever to get fully figured out. Especially to get the password hashing algorithm coded, until stumbling upon the js project listed with the code for it.
Hope this helps others!