我正在 Heroku 上用 Scala 编写一个爱好项目。目前我有自己的身份验证机制,它使用 http 基本身份验证。我希望能够使用人们现有的凭据,例如 google 或 facebook。我知道对于 Ruby 来说,omniauth 应该可以解决问题。是否有适用于 Heroku 的 Scala 等效解决方案?我使用 Scalatra 作为网络堆栈。
问问题
261 次
2 回答
1
从未使用过自己,但您可能想看看socialauth库。
于 2013-05-09T09:10:16.940 回答
0
现在用openid4java 破解了一些最小的东西。文档不是很好,但我已经设法使用我的谷歌帐户登录。
这是我在 servlet 中使用的代码:
package auth
import org.openid4java.discovery.Identifier
import org.openid4java.discovery.DiscoveryInformation
import org.openid4java.message.ax.FetchRequest
import org.openid4java.message.ax.FetchResponse
import org.openid4java.message.ax.AxMessage
import org.openid4java.message._
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.util.List
import org.openid4java.consumer.{VerificationResult, ConsumerManager}
case class AuthenticatedUser(identifier: Identifier, email: Option[String])
class OpenIdConsumer {
val manager: ConsumerManager = new ConsumerManager
def authenticateGoogleUser(request: HttpServletRequest, response: HttpServletResponse) {
val googleOpenIdRequestString = "https://www.google.com/accounts/o8/id"
val returnToUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/openid"
authRequest(googleOpenIdRequestString, returnToUrl, request, response)
}
def authRequest(userSuppliedString: String, returnToUrl: String, httpReq: HttpServletRequest, httpResp: HttpServletResponse) {
val discoveries = manager.discover(userSuppliedString)
val discovered = manager.associate(discoveries)
httpReq.getSession.setAttribute("openid-disc", discovered)
val authReq = manager.authenticate(discovered, returnToUrl)
val fetch = FetchRequest.createFetchRequest
fetch.addAttribute("email", "http://schema.openid.net/contact/email", true)
authReq.addExtension(fetch)
httpResp.sendRedirect(authReq.getDestinationUrl(true))
}
def verifyResponse(httpReq: HttpServletRequest): Either[String, AuthenticatedUser] = {
try {
doVerifyResponse(httpReq)
}
catch {
case e: Exception => {
e.printStackTrace
Left(e.getMessage)
}
}
}
private def doVerifyResponse(httpReq: HttpServletRequest): Either[String, AuthenticatedUser] = {
val response: ParameterList = new ParameterList(httpReq.getParameterMap)
val discovered: DiscoveryInformation = httpReq.getSession.getAttribute("openid-disc").asInstanceOf[DiscoveryInformation]
val receivingURL: StringBuffer = httpReq.getRequestURL
val queryString: String = httpReq.getQueryString
if (queryString != null && queryString.length > 0) receivingURL.append("?").append(httpReq.getQueryString)
val verification: VerificationResult = manager.verify(receivingURL.toString, response, discovered)
val verified: Identifier = verification.getVerifiedId
if (verified != null) {
val authSuccess: AuthSuccess = verification.getAuthResponse.asInstanceOf[AuthSuccess]
if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
val fetchResp: FetchResponse = authSuccess.getExtension(AxMessage.OPENID_NS_AX).asInstanceOf[FetchResponse]
val emails: List[_] = fetchResp.getAttributeValues("email")
val email: String = emails.get(0).asInstanceOf[String]
return Right(AuthenticatedUser(verified, Some(email)))
}
return Right(AuthenticatedUser(verified, None))
}
Left("Not authenticated")
}
}
我的 servlet 现在包含这些入口点来测试它:
val consumer = new OpenIdConsumer
...
get("/authenticate") {
consumer.authenticateGoogleUser(request, response)
}
get("/openid") {
val retval = consumer.verifyResponse(request)
println("retval: " + retval)
<html>
<body>
<h1>Openid return page</h1>
</body>
</html>
}
于 2013-05-09T15:52:33.087 回答