Scala Lift: единообразная аутентификация с авторизацией на основе форм и базовой аутентификацией HTTP? - PullRequest
3 голосов
/ 19 февраля 2012

Я использую Lift (Scala Webframework) с RestHelper для предоставления веб-приложения, а также веб-службы.Пользователи могут использовать HTML-формы веб-приложения или поочередно писать свои собственные сервисные клиенты, используя REST API.HTML-формы будут в основном реализованы с JQuery с использованием REST API с AJAX, чтобы избежать дублирования функций.Я хотел бы защитить REST API, используя HTTP Basic Auth (или что-то подобное).Я также хочу видеть, что пользователям, которые входят в веб-приложение с использованием стандартной формы входа в систему, не нужно выполнять дополнительную базовую аутентификацию (поскольку у них уже есть сеанс, созданный во время входа в систему на основе формы).Как я могу сделать это с помощью Lift?

В настоящее время я настраиваю HTTP Basic Auth:

// Use Basic Authentication
LiftRules.authentication = HttpBasicAuthentication("lift") { 
  case (email, password, req) => {
User.find(By(User.email, email)) match {
      case Full(user) if user.password.match_?(password) => {
    userRoles(List(AuthRole("user"), AuthRole(user.id.toString)))
    User.logUserIn(user)
        true
      }
      case _ => false
} 
  }
} 

и определяю мои защищенные ресурсы REST API следующим образом:

// Protect REST API resources with Basic Auth (but only if user has no Session)
LiftRules.httpAuthProtectedResource.prepend{
  case Req("api" :: "users" :: userId :: _, _, _) =>
User.currentUser match {
  // if the user has already signed in per form we grant access
  case Full(user) => Empty 
  case _ => Full(AuthRole(userId))
}
} 

К сожалению, это не работает, и User.currentUser всегда не возвращает ни одного пользователя.Я где-то читал, что это связано с тем, что пользовательский сеанс еще не инициализирован на этом этапе жизненного цикла запроса.

Есть ли способ в Lift просто защитить ресурсы, независимо от того, какой метод аутентификации используется?В принципе мне все равно, как аутентифицировался пользователь (аутентификация формы, базовая аутентификация, аутентификация дайджеста).И если он прошел аутентификацию с помощью входа в систему на основе форм, я не хочу вызывать у него основную аутентификацию, когда он пытается получить доступ к ресурсам API REST (например, html-формы веб-приложения будут делать это при выполнении AJAX-вызовов к API REST).

1 Ответ

1 голос
/ 25 марта 2014

Код, выполненный в LiftRules.httpAuthProtectedResource, выполняется в области без сохранения состояния.Поэтому у вас нет доступа к каким-либо ранее созданным SessionVars.

Один из способов реализовать ваш случай на мой взгляд:

  1. Создать RESTful API в области без сохранения состояния, использующейauth
  2. Создайте второй API в области с сохранением состояния, который проверяет сеансовую аутентификацию.

Вы можете использовать правила перезаписи для сопоставления одного с другим после выполнения аутентификации.

...