Scala:如何使用google/facebook凭据通过Heroku上的openID为我的应用程序提供访问控制

Scala:如何使用google/facebook凭据通过Heroku上的openID为我的应用程序提供访问控制,scala,heroku,openid,credentials,scalatra,Scala,Heroku,Openid,Credentials,Scalatra,我正在和Scala一起写一个关于Heroku的爱好项目。目前我有自己的身份验证机制,它使用http基本身份验证。我希望能够使用人们的现有凭证,例如谷歌或facebook。我知道对于Ruby来说,omniauth应该起到作用。对于在Heroku上工作的Scala,有没有等效的解决方案?我正在使用Scalatra作为web堆栈。从未使用过我自己,但您可能会想看看库。从未使用过我自己,但您可能会想看看库。现在将一些最小的东西拼凑在一起。文档不是很好,但我已经设法用我的google帐户登录了 以下是我在

我正在和Scala一起写一个关于Heroku的爱好项目。目前我有自己的身份验证机制,它使用http基本身份验证。我希望能够使用人们的现有凭证,例如谷歌或facebook。我知道对于Ruby来说,omniauth应该起到作用。对于在Heroku上工作的Scala,有没有等效的解决方案?我正在使用Scalatra作为web堆栈。

从未使用过我自己,但您可能会想看看库。

从未使用过我自己,但您可能会想看看库。

现在将一些最小的东西拼凑在一起。文档不是很好,但我已经设法用我的google帐户登录了

以下是我在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>
  }
val consumer=new OpenIdConsumer
...
获取(“/authenticate”){
consumer.authenticateGoogleUser(请求、响应)
}
获取(“/openid”){
val retval=消费者。验证响应(请求)
println(“retval:+retval”)
Openid返回页
}

现在就把一些最小的东西拼凑在一起。文档不是很好,但我已经设法用我的google帐户登录了

以下是我在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>
  }
val consumer=new OpenIdConsumer
...
获取(“/authenticate”){
consumer.authenticateGoogleUser(请求、响应)
}
获取(“/openid”){
val retval=消费者。验证响应(请求)
println(“retval:+retval”)
Openid返回页
}

谢谢!不过对我来说有点太花哨了,我还是选择openid4java。谢谢!不过,对于我的目的来说,有点太花哨了,我选择了openid4java。