Compojure security: authentication and authorization

This article has been archived because much better Clojure resources are available now. Some of my favorite Clojure learning resources include Learn Clojure and Clojure web applications on Heroku. You can also find commercial support at Clojure Core.

19 Comments

Filed under Programming

19 responses to “Compojure security: authentication and authorization

  1. Jordan

    Not bad. Ideally, of course, you’d store the hash of the password instead of the password itself, but looks good so far.

  2. Hi, Jordan. Good to hear from you.

    I forgot about hashing the password. To my inexperienced eye, lack of encryption seems like the bigger security hole here, and I have zero experience with setting it up. Once this application is working to the point of being usable, I need to come back and fix both issues.

  3. Perry Trolard

    Hi Eric,

    Thanks for the posts! I think they’re a great entrypoint into Compojure.

    One note: namespaces in Clojure have a code part & a filesystem part, where components in the namespace must map to components of the classpath-relative filesystem path: my.cool.ns must be in /my/cool/ns.clj. To work properly, the file containing your namespace declaration (ns ericlavigne) should therefore be called ericlavigne.clj. The current setup — site.clj — works so long as you’re calling it as a script, but if you want to refer to it from other code (i.e. namespaces), you’ll have to make sure the ns-filesystem mapping’s in place. See clojure.org/namespaces.

    You may know all this already, but I didn’t want others to get tripped up.

    Best,
    Perry

  4. Hi Perry.

    I was aware that the issue existed but didn’t yet know the details. This setup worked well for the first two articles but, at 157 lines of code, I will soon need to break this program into several files.

  5. If you use a session store that’s client-side (such as simple cookies) then this is pretty insecure since the client can change its cookies arbitrarily. I’m not sure what Jetty uses by default.

    One thing that I feel like I really don’t grasp yet is an understanding of when and how to split things out into namespaces and how to refer to them when they are. (When use is preferred over require; when you should just refer to a value with the namespace before it, etc) Might be a good thing to cover in a future installment since most compojure apps aren’t kept in a single file.

  6. James

    Jetty uses an in-memory session store by default. The cookies only store the keys, which are generated with java.security.SecureRandom, so it’s pretty robust.

    With regards to password hashing, it’s more secure to use an algorithm designed for the job. MD5s and other similar algorithms are designed to be fast – not the sort of thing you want for obscuring passwords – and without salting the same password creates the same hash every time, making it vulnerable to rainbow tables. BCrypt is a password hashing scheme that’s used to hash the passwords in most (all?) modern Unix-like OSes, so it’s pretty well tested. There’s a Java implementation of it called jBCrypt.

  7. Following suggestions by James on the mailing list, I’ll be changing this article to use some of Compojure’s built-in support for forms and extract the username in the URL handling rather than in the views.

    Phil, when to split code into namespaces is not specific to Clojure, but it is definitely important. I’ll split this application into several files, each with a different namespace, and make that the topic of the next article.

    Regarding :use vs :require, :use lets you code with less typing, but :require is easier to understand when reading later and will protect your code from namespace clashes if the public API of one of your libraries expands. In other words, :require is always better long term, so I will set a good example by removing :use in the next article.

  8. Hi Eric. Thanks for these articles. I’m looking forward to the next one.

    Is the current state of this application available in a publicly available source-code repository somewhere? The tall-and-skinny blog format is a bit of a hassle for reference.

  9. John, I plan to add this code to github, but it’s not there yet.

    I also need to update the security article to match the latest version of Compojure. James broke some of the namespaces into several smaller namespaces. I already updated the other two articles, but haven’t gotten to this one yet.

    I’ll be delivering a Clojure presentation to a Java user group this Wednesday, which is why I haven’t had time for articles. I’ll post my slides later this week.

    http://www.codetown.us/events/gatorjug-1

  10. Karsten Lang

    I have taken the above eriklavigne.clj file and modified it to use HSQLDB instead. I simply wanted to see Clojure work and didn’t want to fool around with PostgresSQL just now.

    http://github.com/klang/wrk-clojure/blob/master/projects/journal-server/src/eriklavigne.clj

    A diff between init and head will show what I have done to the file.

    I have changed the way sessions and routes are used. A lot has happened in Compojure land since January I guess. (This is the main reason for my sharing of this.)

    In my repository I have a different step by step version of the two blog posts, I don’t use dosync as things are wrapped into a servlet and should be thread-safe because of that.

    I’ve learned a bit of Clojure and Compojure working through this example, thanks.

  11. Ben

    Hi Eric

    thanks a lot for your posts, they are really great and useful — from the perspective of someone just diving into compojure!

    — Ben

  12. Where does “redirect-to” and “link-to” come from? What namespace do I require to get this example working?

  13. This is a very old example. Compojure has since been broken up into several smaller libraries. The “redirect-to” function is now called “redirect” and is in the “ring.util.response” namespace of the ring library. The “link-to” function moved into the “hiccup.page-helpers” namespace of the “hiccup” library.

    You can find a more in-depth discussion of the changes to Compojure in the following article.

    http://formpluslogic.blogspot.com/2010/04/migrating-from-compojure-032-to-040-and_01.html

    If you are just getting started with Clojure or Compojure, I highly recommend using Leiningen or Cake as a build tool. Any tutorial that doesn’t recommend one of these, and use it, is not worth reading. Unfortunately, my tutorials fit that category (I wrote them before Leiningen existed), and I haven’t found time to update them yet.

  14. THANKS A TON, ERIC!

    I’m already using Leiningen…

    I was looking at your example for the authentication methods (as I’m trying to build the core component of my social network app for a class project) and couldn’t figure out where link-to came from. I did discover redirect, nonetheless!

    Your response has helped a lot! MUCH OBLIGED!

    Thanks again,

    shree

  15. If you need authentication and authorization for your application, you should also look at Brenton Ashworth’s sandbar library, which helps with that.

    https://github.com/brentonashworth/sandbar

  16. @Eric, what about the “session”. What namespace does that come under (now)?

  17. Sessions have changed a lot. The following article does a lot of crazy stuff with sessions, which I definitely wouldn’t recommend, but reading the article will give you a good idea of how sessions work now.

    http://cleancode.se/2010/08/30/getting-started-with-compojure.html

    Also, Brenton Ashworth didn’t like the changes to how sessions were handled, so the “sandbar” library that I mentioned earlier supports an alternative that is more like the old way.

    http://stackoverflow.com/questions/3859017/how-do-you-use-sessions-with-compojure-ring

  18. Thanks Eric,

    I’m getting a bit overwhelmed with all the conflicted information out there (as you mentioned sandbar’s different implementation of sessions, for example). Thanks for the links. I hope I’m able to figure things out. Sessions are important to any web based app! Just as is logging in, etc.

    BOY!

Leave a reply to Mulay, Shree R. Cancel reply