#scala #lift #basic-authentication
#scala #отменить #базовая аутентификация
Вопрос:
Я использую приведенный ниже код, чтобы иметь базовую аутентификацию HTTP в моем приложении и преобразовать ответ в случае несанкционированного доступа. Это не работает. Что здесь не так?
// Http Basic Authentication
LiftRules.authentication = HttpBasicAuthentication("xxx") {
case (userName, userPass, _) => {
Console.println("Authenticating: " userName)
User.find("userName", userName).map {
user =>
if (user.password.isMatch(userPass)) {
Account.authenticatedUser.setFieldsFromDBObject(user.asDBObject)
userRoles(AuthRole("authorisedUser"))
Console.println("Success: " userName)
true
}
else {
Console.println("Failed: " userName)
false
}
} openOr false
}
}
LiftRules.responseTransformers.append {
resp => resp match {
case UnauthorizedResponse("xxx") =>
Console.println("Responding modified...");
JsonUnauthorizedResponse(("error" -> "Incorrect username or password"))
case x => Console.println("Responding..."); x
}
}
Я не получаю измененный ответ для URL-адресов в RestApiHelper
объект.
Может кто-нибудь, пожалуйста, указать мне, как я могу изменить ответ для
URL-адреса Rest Api в случае несанкционированного ответа. Я не собираюсь делать
это с использованием кодов состояния. Поскольку я создаю API, который будет использоваться
мобильные приложения с управляемыми сервером ответами на ошибки для обеспечения согласованности и
множество других факторов.
ОБНОВЛЕНИЕ решения: этот следующий переопределенный класс case, основанный на ответе CheatEx, сработал для меня:
case class JsonHttpBasicAuthentication(realmName: String)(func: PartialFunction[(String, String, Req), Boolean]) extends HttpAuthentication {
def credentials(r: Req): Box[(String, String)] = {
header(r).flatMap(auth => {
val decoded = new String(Base64.decodeBase64(auth.substring(6, auth.length).getBytes)).split(":").toList
decoded match {
case userName :: password :: _ => Full((userName, password))
case userName :: Nil => Full((userName, ""))
case _ => Empty
}
}
)
}
override def realm = realmName
def verified_? = {
case (req) => {
credentials(req) match {
case Full((user, pwd)) if (func.isDefinedAt(user, pwd, req)) =>
func(user, pwd, req)
case _ => false
}
}
}
override def unauthorizedResponse: UnauthorizedResponse = new UnauthorizedResponse(realm) {
override def toResponse = {
val errResp: JValue = ("error" -> "Incorrect username or password")
InMemoryResponse(errResp.toString.getBytes("UTF-8"),
S.getHeaders(Nil), S.responseCookies, 200)
}
}
}
Ответ №1:
У меня была та же проблема с несанкционированным ответом Lift по умолчанию. Мое решение состояло в переопределении unauthorizedResponse
метода HttpAuthentication
признака. Вот пример кода:
private object MyHttpAuth extends HttpAuthentication {
override def realm: String = "MyApp"
def verified_? : PartialFunction[Req, Boolean] = {
case req: Req => getUser(req) match {
case Some(userId) => {
userRoles(AuthRole(userId)::Nil)
true
}
case None => false
}
}
override def unauthorizedResponse: UnauthorizedResponse = new UnauthorizedResponse(realm) {
override def toResponse = InMemoryResponse(Array(), Nil, Nil, 401)
}
}