User management - what path to take?

Hey,

What is a good option for building user management functionality in a clojure web app? So far I’ve read that many just make their own. Another option seems https://github.com/cemerick/friend. Alternatively maybe take a stab at using spring security?

Thanks!

6 Likes

I am not sure, but I think Buddy is more widely used these days. Spring security is probably not a path you want to take with Clojure, based on the amount of annotations (SpringBoot) and XML (Spring).

3 Likes

Haven’t actually used it myself, but I think Apache Shiro can be used from Clojure, unlike Spring Security, it doesn’t use many annotations I think.

1 Like

This is a great question I want more light on, too; I have rolled my own authorization, leaning on 3rd party CAS for validation whenever I can, but definitely feels like a large hole in my understanding compared to the evolved state of things in my other realm, Wordpress land.

I would love to know more if anyone has done this. Apache Shiro is new to me but looks promising (and I’m a fan of Apache work), but the demo video with all the XML config stuff is a bit bewildering to me; with my leiningen setups, I’m not sure how to translate all that XML stuff. Any ideas?

EDIT: Just discovered a 6-year old (!!) Clojure wrapper for Shiro, Poceshiro. I wouldn’t expect it to work on modern versions of Shiro, but it is worth a study.

Buddy seems worth considering though its linked resource also mentions Friend as the main tool that is used for this

The most known and used library in clojure for securing your ring webapps is [friend](https://github.com/cemerick/friend). To my knowledge it’s a great library, and you should seriously consider using it for your apps as well.

The main issue this article raises with Friend seems to be when it’s used alongside Liberator.

1 Like

We use https://firebase.google.com/products/auth to let users sign up and login to our web apps.
If you run on AWS there is: https://aws.amazon.com/de/cognito/

1 Like

I found Friend to be very opinionated and designed for a specific use case. I ended up rolling my own solution using Buddy (an excellent set of tools!).

I don’t think this is a solved problem. The FAQ for Sente (which I use) says:

“How do I integrate Sente with my usual login/auth procedure?
This is trivially easy as of Sente v0.13.0+.”

I think this is far from trivial and this area is still looking for a good library. Buddy is great, but it’s a set of screwdrivers, essentially, not an authentication and user management solution for webapps.

2 Likes

Thanks, will keep in mind.

Great idea, will look into using firebase for this, initial impression is good. I’ve used the db before, but not auth. As previous posters have said, looks like there isn’t an agreed way of doing this and firebase looks to be a fully working solution that’s quick to implement, so definitely better than to roll my own as my needs aren’t that complicated.

1 Like

Keycloak, an Open Source IAM product, is also a good solution to consider for basic user management and security related topics (authentication, authorization, etc.).
I did some work to ease the integration in the Clojure ecosystem : https://github.com/jgrodziski/keycloak-clojure
Feel free to ask any questions.

2 Likes

Have you considered a managed service like Auth0 or AuthRocket? I’ve used Auth0 a few times, and although it can be difficult to work with, it’s usually easier than setting up your own user authentication/management. There’s an example of how to use it in a cljs frontend here, and in a clojure api here.

1 Like

This is a great question.

It’s a good idea to go straight for OpenID-Connect, using a third-party to store users and their passwords. If you go this route, you’ll need to choose an identity provider, such as AWS Cognito, Auth0, Google, onelogin, okta and others. If you want something on-premise, Keycloak is a good choice.

If you do this your Clojure application will need to support the OAuth2 client functionality to integrate with the identity provider. Specifically you’ll have to write a callback that will code the logic for exchanging the OAuth2 code for the identity token containing the user’s details. There is some Ring middleware that might help you here: https://github.com/weavejester/ring-oauth2

You’ll also need to create a session for users, and store session identifiers in a browser cookie. This can get quite involved.

Note if you do decide on AWS Cognito, there’s an option to integrate with AWS Application Load Balancer, you should read this: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html - the benefit is that ALB will perform this code exchange on your behalf, and will even do the cookie/session management, forwarding you the user’s details in custom HTTP request headers.