Shiro based authentication

668 views
Skip to first unread message

Alex Ivanov

unread,
Jul 24, 2013, 5:37:14 AM7/24/13
to spray...@googlegroups.com
I want to write login form authentication for my service on top of Apache Shiro and Spray-routing. I have a login form routes:

pathPrefix("api") {
    path("login") {
      post {
        (hostName & AuthToken.fromRequest) { (host: String, token: AuthToken) =>
          token setHost host
          stormpathAuth(token) { subj =>
            redirect("/some/path", StatusCodes.SeeOther)
          }
        }
      }
    }

That works correctly and under subj i have a correct logged in user, so i redirect him to "/some/path". And here comes my problem. Currently i have the following route:

get {
    path("path") { ctx =>
      if (User.isAuthenticated) ctx.complete(html.page(Page)) 
      else ctx.reject(NoUserLoggedInRejection)
    }

Under user i have a simple alias method for Shiros Subjectdef User = SecurityUtils.getSubject. But this works strange. As i understand, after login step, User should return authenticated Subject, but that not always works as i expect and often redirects me back to the authentication form. 


Age Mooij

unread,
Jul 24, 2013, 5:58:36 AM7/24/13
to spray...@googlegroups.com
It looks like the Apache stuff uses some kind of ThreadLocal-based approach and that is not going to work on an Akka-based system.

Threads in Spray and Akka are pooled and will be heavily reused by multiple actors, so a ThreadLocal approach will not work (and catastrophically so).

You will need to somehow map a request to a user in a threadsafe way. I have no idea whether Shiro can do that sort of thing.

Hope this helps,
Age


--
You received this message because you are subscribed to the Google Groups "spray-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Alex Ivanov

unread,
Jul 24, 2013, 12:36:34 PM7/24/13
to spray...@googlegroups.com
Thanks, you've confirmed my fears. But still i want to make a session tracking mechanism without using cookies and browsers. But i'm not good at security at all. Is it a good idea to take some threadsafe collection, like the one used in spray-caching and as keys i'll take clients IP and Shiro Subjects as values? 

Mark Schaake

unread,
Jul 24, 2013, 1:52:06 PM7/24/13
to spray...@googlegroups.com
It is true that Shiro favors a ThreadLocal-based approach - but that is if you want to use the SecurityUtils static methods that show up all over the place in the Shiro tutorials. For example, you won't be able to do this:

val subj = SecurityUtils.getSubject() // <- this is relying on ThreadLocal

There is an alternative that will allow you to use Shiro with Spary / Akka: build your own subject using org.apache.shiro.subject.Subject.Builder and manage its lifecycle in your application code. You won't be able to use the SecurityUtils static methods (which rely on ThreadLocal), but you'll be able to leverage Shiro's Realm infrastructure.

There is still an issues in that if you want to leverage Shiro's Realms for authentication and authorization - you're going to be blocking threads because it does not have an async API. This means that if you wanted to use a reactive persistence layer for your session store (such as ReactiveMongo), you will have to block in your application code when doing auth checks agains the persistence store.

FYI: I've implemented a security layer using Shiro + Spray as a proof of technology and got it working. My opinion, however, is that you are better off building your own simply due to the lack of an async API. If your main concern is password encryption + salting, I have implemented the Shiro flavor in a project I've been working on called Sprest. You can check it out here:


Sprest is not ready for primetime, so please don't consider depending on it. (Besides, there isn't any documentation :)

Alex Ivanov

unread,
Jul 24, 2013, 2:34:14 PM7/24/13
to spray...@googlegroups.com
Thanks for your answer! It helped a lot.

For user authentication/authorization  i'm using Stormpath, in Shiro i'm interested in session management.

Age Mooij

unread,
Jul 25, 2013, 4:56:46 AM7/25/13
to spray...@googlegroups.com
I would advise against using IP addresses to uniquely identify users since there is no guarantee at all that several users are not using the same (proxy/NAT/etc) IP or that users are switching ip address on the fly (mobile networks, DHCP lease expiry, etc.)

If you want to keep some kind of session, then one way or another your http requests and responses will need to contain some form of session id, either as a cookie, a header, as part of the url, or as part of the payload. Doing this in a secure fashion is non-trivial and depends on the level of security required.

Age
Reply all
Reply to author
Forward
0 new messages