t2v / play2-auth

Play2.x Authentication and Authorization module
Apache License 2.0
608 stars 138 forks source link

Question: How to bypass authentication for crawlers? #58

Open k4200 opened 11 years ago

k4200 commented 11 years ago

質問ってここでいいんでしょうか&英語の方がいいですよね?

Hi,

I started using play2-auth about a week ago, and managed to get it working (more or less). Thanks for the great module!

I'm developing a web site where users can post text, like one of those online forums, and here's my scenario:

Actually, the above requirements have been fulfilled by creating a user in AuthConfigImpl.authenticationFailed.

Now, I don't want to create temporary users for crawlers, and my question is, what's the optimal way to achieve that?

Thanks! よろしくお願いします。

gakuzzzz commented 11 years ago

質問はここでもTwitterでもOKです。はい、ここだと英語にして頂けると助かります! I can accept questions in Github Issue or Twitter @gakuzzzz. When you post a question to issue, please write in English.

It may be misplaced kindness... When visitors sign up to become a "Member", your system must invalidate the session cookie, which never expires, and create a new session cookie. Otherwise, your system has a session hijacking vulnerability.

There are two approaches.

best regards,

k4200 commented 11 years ago

Thanks for the answer and the advice for the session issue.

There are two approaches.

  • When use AuthConfig#authenticationFailed, you can access the RequestHeader and User-Agent header.
  • You can user AuthenticationElement instead of AnthElement and create new Element of StackableController that handle Option[User] and RequestHeader.

I chose the former. Now, my code is like the following and I'm not sure what to do in authenticationFailed. I'm still not used to this module, so my understanding might be fundamentally wrong...

object Auth extends Controller with LoginLogout with AuthConfigImpl {
  def authenticate = Action { implicit request =>
    request.session.get("user_id").map{userId =>
      gotoLoginSucceeded(userId.toInt)
    }.getOrElse{
      BadRequest("direct access?")
    }
  }
}

trait AuthConfigImpl extends AuthConfig {
  def authenticationFailed(request: RequestHeader): Result = {
    request.headers.get("X-Requested-With") match {
      case Some("XMLHttpRequest") =>
        Unauthorized("Authentication failed")
      case _ =>
        if (!UserAgent.isCrawler(request)) {
          val gu = GuestUser.create
          Redirect(routes.Auth.authenticate).withSession("access_uri" -> request.uri, "user_id" -> gu.id.toString)
        } else {
          // This won't work since crawlers don't accept cookies.
          Redirect(routes.Auth.authenticate).withSession("access_uri" -> request.uri, "user_id" -> CrawlerUser.id.toString)
        }
    }
  }
}

Thanks!