2011-04-26 62 views
2

我正在使用下面的代碼在我的應用中使用HTTP Basic Auth,並在未授權訪問的情況下使用 轉換響應。這不是 工作。這裏有什麼問題?使用LiftRules.responseTransformers修改對Auth失敗的響應

// 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 
     } 
    } 

我沒有收到在RestApiHelper 對象的URL修改的響應。 有人可以請我指出如何修改 Rest Api Url在未授權響應情況下的響應。我不打算使用狀態碼來執行 。由於我創建了一個API供 服務器使用,服務器控制錯誤響應的一致性和 許多其他因素。

解決方案UPDATE:基於由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) 
    } 
    } 
} 

回答

2

我與Lift的默認授權響應了同樣的問題。我的解決方案是重寫特徵的方法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) 
    } 
    }