Better password security

This commit is contained in:
thosakwe 2017-03-04 16:40:01 -05:00
parent d6e74efe0e
commit 84bcb05fdd
5 changed files with 23 additions and 13 deletions

4
.vscode/launch.json vendored
View file

@ -6,7 +6,7 @@
"type": "dart-cli", "type": "dart-cli",
"request": "launch", "request": "launch",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"debugSettings": "${command.debugSettings}", "debugSettings": "${command:debugSettings}",
"program": "${workspaceRoot}/bin/server.dart", "program": "${workspaceRoot}/bin/server.dart",
"args": [] "args": []
}, },
@ -15,7 +15,7 @@
"type": "dart-cli", "type": "dart-cli",
"request": "launch", "request": "launch",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"debugSettings": "${command.debugSettings}", "debugSettings": "${command:debugSettings}",
"program": "${workspaceRoot}/bin/multi_server.dart", "program": "${workspaceRoot}/bin/multi_server.dart",
"args": [] "args": []
} }

View file

@ -3,7 +3,7 @@ library angel.models.user;
import 'package:angel_framework/common.dart'; import 'package:angel_framework/common.dart';
class User extends Model { class User extends Model {
String email, username, password; String email, username, password, salt;
final List<String> roles = []; final List<String> roles = [];
User( User(
@ -11,6 +11,7 @@ class User extends Model {
this.email, this.email,
this.username, this.username,
this.password, this.password,
this.salt,
Iterable<String> roles: const []}) { Iterable<String> roles: const []}) {
this.id = id; this.id = id;
this.roles.addAll(roles ?? []); this.roles.addAll(roles ?? []);

View file

@ -13,12 +13,15 @@ class AuthController extends Controller {
/// Attempt to log a user in /// Attempt to log a user in
LocalAuthVerifier localVerifier(UserService userService) { LocalAuthVerifier localVerifier(UserService userService) {
return (String username, String password) async { return (String username, String password) async {
List<User> users = await userService.index({'query':{'username': username}}); List<User> users = await userService.index({
'query': {'username': username}
});
if (users.isNotEmpty) { if (users.isNotEmpty) {
var hash = hashPassword(password); return users.firstWhere((user) {
return users.firstWhere((user) => user.password == hash, var hash = hashPassword(password, user.salt, app.jwt_secret);
orElse: () => null); return user.username == username && user.password == hash;
}, orElse: () => null);
} }
}; };
} }
@ -29,8 +32,8 @@ class AuthController extends Controller {
auth = new AngelAuth(jwtKey: app.jwt_secret) auth = new AngelAuth(jwtKey: app.jwt_secret)
..serializer = serializer ..serializer = serializer
..deserializer = deserializer ..deserializer = deserializer
..strategies.add( ..strategies.add(new LocalAuthStrategy(
new LocalAuthStrategy(localVerifier(app.container.make(UserService)))); localVerifier(app.container.make(UserService))));
await super.call(app); await super.call(app);
await app.configure(auth); await app.configure(auth);

View file

@ -1,6 +1,7 @@
import 'package:angel_common/angel_common.dart'; import 'package:angel_common/angel_common.dart';
import 'package:crypto/crypto.dart' show sha256; import 'package:crypto/crypto.dart' show sha256;
import 'package:mongo_dart/mongo_dart.dart'; import 'package:mongo_dart/mongo_dart.dart';
import 'package:random_string/random_string.dart' as rs;
import '../models/user.dart'; import '../models/user.dart';
import '../validators/user.dart'; import '../validators/user.dart';
export '../models/user.dart'; export '../models/user.dart';
@ -15,14 +16,18 @@ configureServer(Db db) {
service.beforeCreated service.beforeCreated
..listen(validateEvent(CREATE_USER)) ..listen(validateEvent(CREATE_USER))
..listen((e) { ..listen((e) {
e.data['password'] = hashPassword(e.data['password']); var salt = rs.randomAlphaNumeric(12);
e.data
..['password'] =
hashPassword(e.data['password'], salt, app.jwt_secret)
..['salt'] = salt;
}); });
}; };
} }
/// SHA-256 hash any string, particularly a password. /// SHA-256 hash any string, particularly a password.
String hashPassword(String password) => String hashPassword(String password, String salt, String pepper) =>
sha256.convert(password.codeUnits).toString(); sha256.convert(('$salt:$password:$pepper').codeUnits).toString();
/// Manages users. /// Manages users.
/// ///

View file

@ -7,4 +7,5 @@ final Validator USER = new Validator({
}); });
final Validator CREATE_USER = USER.extend({}) final Validator CREATE_USER = USER.extend({})
..requiredFields.addAll(['email', 'username', 'password']); ..requiredFields.addAll(['email', 'username', 'password'])
..forbiddenFields.addAll(['salt', 'roles']);