Getting `org.scalatra.ScalatraKernel$HaltException: null` in `basicAuth`

110 views
Skip to first unread message

missingfaktor

unread,
May 15, 2012, 3:03:19 AM5/15/12
to Scalatra
Hello everyone.

I have implemented basic authentication in my servlet by following the method suggested here [ https://github.com/jlarmstrong/scalatra-auth-example ] and here [ https://gist.github.com/985761 ]. However when I run the tests, I get following error wherever I have invoked `basicAuth` method inside the servlet:

org.scalatra.ScalatraKernel$HaltException: null
11:58:45.872 [qtp30641031-26 - /snark/login?userName=natsu&password=dragneel] DEBUG org.eclipse.jetty.server.Server - RESPONSE /snark/login  401
11:58:45.872 [qtp30641031-26] DEBUG o.e.j.server.AbstractHttpConnection - closed BlockingHttpConnection@fa6240,g=HttpGenerator{s=4,h=-1,b=-1,c=-1},p=HttpParser{s=7,l=0,c=0},r=1
11:58:45.900 [qtp30641031-24] DEBUG org.eclipse.jetty.http.HttpParser - filled 1073/1073

Here is the relevant part of the servlet:

    post("/login") {
    loggingExceptionOn("login") {
      basicAuth
      logger.debug("The user %s was successfully logged in.".format(params("userName")))
    }
  }

The key differences in my servlet from the example servlet I linked above:
1. I am using MySQL (along with Squeryl) instead of MongoDb.
2. I am using ScalatraServlet instead of ScalatraFilter.

What could be I doing wrong? Please help!

--
Cheers,

missingfaktor

unread,
May 16, 2012, 1:48:04 AM5/16/12
to Scalatra
Looking thru the Scalatra source, I figured out how to make the request. The following did it:

      val headers = Map("Authorization" ->  "basic " + new String(Base64.encodeBytes((userName + ":" + password).getBytes)))
      val credentials = Map("userName" -> userName, "password" -> password)
      // Send credentials as params, and headers as headers.

Now I have a new question: Is it possible to do basic authentication without involving session management at all?

Any help will be greatly appreciated.
--
Cheers,

Ivan Porto Carrero

unread,
May 16, 2012, 3:21:56 AM5/16/12
to scalat...@googlegroups.com
If you use scentry it will always involve the session/cookie for storing a single string. It's not going to bloat your session. It's going to use 36 bytes per user if you use a standard uuid string (±36kB for 1000 concurrent users with an active session), with int ids the memory usage it adds is even less.

In the case of basic auth it's not strictly necessary to have session state that's true, but then you also have no need for scentry and the different authentication strategies it provides either. I've increased the visibility of https://github.com/scalatra/scalatra/blob/develop/auth/src/main/scala/org/scalatra/auth/strategy/BasicAuthStrategy.scala#L51. This is in the current snapshot for 2.1.0 on sonatype oss

So if the only way you're going to do auth is through basic auth, then you can still implement basic auth relatively easy yourself: https://gist.github.com/2708163.

Ivan Porto Carrero

unread,
May 16, 2012, 3:30:28 AM5/16/12
to scalat...@googlegroups.com
If you want more examples of authentication strategies, but they may give you some idea on what's possible.

Those examples you can't just copy paste though as I'm building a new version of scentry using that project so some methods may expect different parameters or/and types.

Ross A. Baker

unread,
May 16, 2012, 3:04:07 PM5/16/12
to scalat...@googlegroups.com
scalatra-auth provides a framework for most common use cases, and can
be extended to others. If it's too heavy, or makes assumptions that
don't fit your needs, there are some other tricks that can be done
entirely inside core. (No compiler handy, may require a little
tweaking.)

// Define this however you want
def isAuthorized(implicit request: HttpServletRequest): Boolean

// before filters take the same kind of path matchers as routes do
before("/protected/*") {
if (!isAuthorized(request))
halt(403)
}

get("/protected/foo/:id") {
// protected by before filter.
}

If you don't like before filters, you can create something like this:

// reusable logic that gets explicitly applied. Not as concise as
a before filter,
// but a little less magical.
def ifAuthorized(authorized: => Any)(forbidden: => Any = { halt(403) }) = {
if (isAuthorized(request)) authorized else forbidden
}

get("/protected/foo/:id") {
ifAuthorized {
showFoo(params("id"))
--
Ross A. Baker
ba...@alumni.indiana.edu
Indianapolis, IN, USA

missingfaktor

unread,
May 17, 2012, 1:27:42 AM5/17/12
to scalat...@googlegroups.com
Thanks a lot, Ivan and Ross. That was a great help.
--
Cheers,

Reply all
Reply to author
Forward
0 new messages