我正在编写一个Play应用程序,我需要将身份验证也由另一个Web应用程序处理。因此,当用户登录到其他Web应用程序时,它还应该登录Play应用程序。
要在Play中实现安全性,我使用了Play Framework文档中的说明:http://www.playframework.com/documentation/2.0.1/ScalaSecurity
我对如何进行外部身份验证的想法是让其他应用程序执行ajax调用以登录Play应用程序,因为我认为这会为用户编写会话cookie。但这不起作用。我仍然需要手动登录Play应用程序。
这是我的控制器:
val loginForm = Form(
tuple(
"username" -> nonEmptyText,
"password" -> nonEmptyText) verifying("Invalid email or password!", result => result match {
case (email, password) => Admin.authenticate(email, password)
}))
def jsLogin = Action {
implicit request => {
loginForm.bindFromRequest.fold(
formWithErrors => BadRequest(toJson("Unauthorized!")),
user => {
Ok(toJson("Ok")).withHeaders(
ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
ACCESS_CONTROL_ALLOW_METHODS -> "POST",
ACCESS_CONTROL_MAX_AGE -> "300",
ACCESS_CONTROL_EXPOSE_HEADERS -> "Origin, X-Requested-With, Content-Type, Accept"
).withSession("email" -> user._1)
})
}
}
以下是我用来测试的代码:
$.ajax({
type: "POST",
url: "http://localhost:9000/jsLogin",
data: {
username: "username",
password: "password"
}
})
调试之后,我知道jsLogin方法工作正常,它确实记录了用户,响应对ajax方法没问题。但是当我尝试访问我的播放应用程序时,它仍然要求我手动登录。
是否有一些让用户从外面登录的非常方便的方式?
答案 0 :(得分:1)
好的,我得到了它的工作。我注意到,调用返回的Set-Cookie标头被认为是不安全的。要解决此问题,我必须正确获取CORS标头并发送凭据。所以这是我的新查询(出于调试原因,使用XmlHttpRequest代替jQuery的ajax,也应该使用ajax)。
var xmlhttp = new XMLHttpRequest();
var url = "http://localhost:9000/jsLogin";
var params = "username=username&password=password";
xmlhttp.open("POST", url, true);
xmlhttp.withCredentials = true;
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(params);
这是播放控制器
def jsLogin = Action {
implicit request => {
loginForm.bindFromRequest.fold(
formWithErrors => BadRequest(toJson("Unauthorized!")),
user => Ok(toJson("Ok")).withHeaders(
ACCESS_CONTROL_ALLOW_ORIGIN -> "http://sending.host.url",
ACCESS_CONTROL_ALLOW_METHODS -> "POST",
ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true",
ACCESS_CONTROL_ALLOW_HEADERS -> "Origin, X-Requested-With, Content-Type, Accept").withSession("email" -> user._1)
})
}
}
所以解决方法是在客户端和服务器端使用“withCredentials = true”正确设置CORS标头。
答案 1 :(得分:0)
所以你想通过使用Play的会话cookie来处理安全问题?在AJAX请求之后你检查过cookie实际上是否存在? “另一个”应用是否位于同一个域中?如果不是,那么其他应用程序将不会使用该cookie。
顺便说一句,詹姆斯·沃德in a blog post描述了一种更好的处理方法。