4

認証を別の Web アプリケーションでも処理する必要がある Play アプリケーションを作成しています。そのため、ユーザーが他の 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 メソッドに正常に送信されることがわかりました。しかし、自分のプレイ アプリケーションにアクセスしようとすると、手動でログインするよう求められます。

ユーザーを外部からログインさせるための面倒ではない方法はありますか?

4

2 に答える 2

1

わかりました、私はそれを働かせました。私が気付いたのは、呼び出しによって返された Set-Cookie ヘッダーが安全でないと見なされたことです。これを修正するには、CORS ヘッダーを正しく取得して資格情報を送信する必要がありました。ここに私の新しいクエリがあります(デバッグの理由でjQueryのajaxの代わりにXmlHttpRequestを使用しましたが、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 ヘッダーを正しく設定することでした。

于 2013-07-10T06:09:31.540 に答える