play framework — реализация безопасного социального доступа пользователя

Я использую Play 2.1 и защищенный мастер-снимок.

Я реализовал поиск и сохранение UserService (расширяет UserServicePlugin) следующим образом:

Метод поиска, как показано ниже:

 def find(userId: UserId): Option[Identity] = {
    val user = User.findByUserId(userId);
    user match {
      case Some(user) => {
        val socialUser = new SocialUser(userId, null, null, user.name, Option(user.email), Option(user.photo), AuthenticationMethod("userPassword"), null, null, Some(PasswordInfo(PasswordHasher.BCryptHasher, BCrypt.hashpw(user.password, BCrypt.gensalt(10)))))
        Option(socialUser)
      }
      case None => {
         None
      }
    }
  }

Метод сохранения, как показано ниже:

 def save(user: Identity): Identity = {
    user.id.providerId match {
      case "facebook" => {

      }
      case "google" => {

      }
      case "twitter" => {
      }

      case "userpass" => {
        val eUser = User.findByEmail(user.id.id) match {
          case Some(eUser) => {
            //Existing User - update only
          }
          case None => {
            val appUser: User = new User(NotAssigned, "student", user.id.providerId, user.fullName, user.id.id, user.passwordInfo.get.password, null, null, null, null, null, "active")
            User.create(appUser)
          }
        }
      }
    }
    user
  }

При сохранении (регистрации) пароль зашифровывается в базу данных, я не уверен, должен ли он быть зашифрован или нет, и выше всегда говорится: «Введенные вами учетные данные недействительны».

Но если я использую слово «пароль» (строка) вместо user.password (из базы данных) в методе поиска, как показано ниже, он правильно проверяет учетные данные и регистрирует меня:

    val socialUser = new SocialUser(userId, null, null, user.name, Option(user.email), Option(user.photo), AuthenticationMethod("userPassword"), null, null, Some(PasswordInfo(PasswordHasher.BCryptHasher, BCrypt.hashpw("password", BCrypt.gensalt(10)))))

Здесь я думаю, что он снова пытается зашифровать пароль из базы данных (которая уже зашифрована) ... Думаю, мне следует либо сохранить пароль без шифрования, либо получить пароль, введенный пользователем на странице входа, для использования в методе поиска . Может ли кто-нибудь помочь мне, спасибо.

Я считаю, что следующие две точки входа для всех социальных сетей и провайдера UserPass!

Точки входа провайдеров

GET /authenticate/:provider securesocial.controllers.ProviderController.authenticate(провайдер)

POST /authenticate/:provider securesocial.controllers.ProviderController.authenticateByPost(поставщик)

Я думаю, что эти реализации поставляются с безопасным социальным плагином? или надо повторить то же самое? Это лучшее решение!!

Я использую MySQL, и ниже приведена моя таблица:

create table t_users (
    id int unsigned not null auto_increment,
    user_type enum('admin', 'user') not null default 'user',
    login_type set('userpass', 'facebook', 'google', 'twitter') not null default 'userpass',
    name varchar(64) not null,
    email varchar(128) null,
    password varchar(128),
    mobile varchar(10) null,
    facebook varchar(64) null,
    google varchar(64) null,
    twitter varchar(64) null,
    photo varchar(128),
    status enum('registered', 'active', 'suspended', 'deleted') not null default 'registered',
    modified timestamp not null,
    last_login timestamp not null,
    primary key (id),
    unique(email),
    unique(facebook),
    unique(google),
    unique(twitter)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

person user237865    schedule 20.04.2013    source источник


Ответы (2)


Вам нужно где-то использовать BCrypt.checkpw(suppliedPassword, hashedPassword).

Так что да, вы должны сохранить хешированный пароль в базе данных. Затем, когда пользователь вводит пароль на экране входа в систему, вы должны получить хешированный пароль для пользователя из своей базы данных, вызвать checkpw, а затем, если он возвращает true, войдите в систему.

person sthomps    schedule 21.04.2013
comment
POST /authenticate/:provider securesocial.controllers.ProviderController.authenticateByPost(provider) Приведенная выше строка является реализацией по умолчанию Authentication of the UserPass? Это? Если да, то вы говорите, должны ли мы обновить или заменить его вышеуказанным методом checkpw? - person user237865; 21.04.2013
comment
SecureSocial должен автоматически выполнять все хеширование за вас. Итак, похоже, что ваш метод find() неверен. В вашем коде похоже, что вы хешируете уже хешированный пароль. Вы должны иметь возможность скопировать демонстрационный проект и изменить его по мере необходимости: github.com/jaliss/securesocial/tree/master/samples/scala/demo - person sthomps; 21.04.2013
comment
Я видел образец, они не используют пароль или bcrypt или что-то еще, но я обнаружил проблему, я пытаюсь снова зашифровать пароль, например BCrypt.hashpw(user.password, BCrypt.gensalt(10)), который на самом деле должен быть просто user.password. Я не знаю, почему я это делал :( Спасибо за обсуждение :) Я действительно ценю это. - person user237865; 22.04.2013

Правильный метод поиска, как показано ниже:

 def find(userId: UserId): Option[Identity] = {
    val user = User.findByUserId(userId);
    user match {
      case Some(user) => {
        val socialUser = new SocialUser(userId, null, null, user.name, Option(user.email), Option(user.photo), AuthenticationMethod("userPassword"), null, null, Some(PasswordInfo(PasswordHasher.BCryptHasher, user.password)))
        Option(socialUser)
      }
      case None => {
         None
      }
    }
  }
person user237865    schedule 22.04.2013