lcabrini

lcabrini

I’m relatively new to both Phoenix and Ash. I followed the getting started guides to get up and running and now have ash authentication working and a basic phoenix live view that is only available upon login.

To help me to learn more, I’m trying to rewrite a few old projects in Ash and Phoenix. In the current case, I need to login with username and password. No need for tokens. Users cannot register themeselves. I’ve got all that working fine.

The next issue is to redirect back to the login page with an authentication error on failed login. Currently it redirects to another page (as per the getting started guide).

I’ve been reading through the sources of ash_authentication_phoenix and I have found reference to authentication_error_container_class and authentication_error_text_class, which are in the default overrides. This indicates that it should be possible to pass an error message to the login form. But I just can’t seem to figure out how to go about it. I can’t find the name of what to set in order for that authentication error to display on the login page.

Perhaps a bit more curious is that, of the few projects I seem to have found that use ash_authentication_phoenix, not one of them seems to redirect back to the login page on failure. Is there are reason for this? Am I the one that doesn’t understand something basic, perhaps security related or something?

First 10 of 17 Posts Switch mode

lcabrini

lcabrini OP

For the time being I simply solved it by redirecting back to the login form. It would have been nice to display an “Authentication failed” message as well, but no matter what I try (flash or otherwise), it’s not working. At least it’s better than rendering “failure.html”, which in turn renders app.html.heex, which should only be shown to authenticated users.

adw632

adw632

I find authentication is one of those areas that is almost impossible for any framework to do right.

I did use Ash Authentication but in the end I had to remove it and went with PHX gen auth and guardian.

I think the Ash core team are doing an awesome job in making Elixir app development more productive, so I don’t want this to be seen as a criticism of their hard work. I however have significant reservations in respect of Ash Authentication.

Some of the reservations I have include:

  • insufficient escape hatches in handling of actions such as implementing password checks
  • No sign-in audit records or recording invalid signins, no account lock out after too many failed signins.
  • Results in security flaws as users should not be able to brute force passwords or tokens unfettered.
  • Lack of control over controller flows, like confirmation and in your case redirects, it’s all concreted up and difficult to reason about.
  • Lack of customisation of the UI and view
  • Use of pow which does not yet officially support liveview sockets
  • Inability to add TOTP
  • Still requires a lot of touch points on the codebase to implement and what you’re left with is quite inflexible.

In my view the Ash Authentication approach is too inflexible, noting the above limitations and security concerns. The Phoenix Ash Authentication integration is also a step too far as you don’t get a normal liveview experience with a template or components to work with. IMO generating a regular liveview with a render function or heex template is the right thing to do here. Yes that is not the Ash way to generate code, but I argue the Ash philosophy of “deriving the rest” doesn’t hold for view/UI concerns and any attempt at “liveview escape hatches” will be both cumbersome and alien vs having a regular liveview module in your code base that you can change as you see fit.

The taste that Ash Authentication left, borderlined on a near rejection of the entire “Ash way” as far too risky. But just removing Ash Authentication I got the necessary flexibility, security, and control back.

My view is if you limit Ash to the resource/domain model concerns, use the Ash code API as you would a Phoenix context and the Ash Phoenix forms support then Ash delivers significant value. The highlights besides the powerful resource model are authorisation / access policies, multi-tenancy, easy APIs and automatic migrations as a bonus.

There is sufficient flexibility and escape hatches in the core of Ash to do anything you need, which is sadly not the case with Ash Authentication which necessarily has to reach up into the view/controller layer.

lcabrini

lcabrini OP

Thank you for your reply. You are pretty much reflecting what I was thinking. But I also thought that maybe it’s just that I haven’t learned enough about Ash, or in the case Ash Authentication yet and that there would be a simple, obvious way to implement what I wanted.

Just like you, I really don’t want to seem like I’m criticizing Ash as a whole. So far so good on that front. I’m still figuring a lot out, so I’m going to continue experimenting a bit.

jimsynz

jimsynz

Ash Core Team

Hi @lcabrini :wave:

My original intent was that putting the correct behaviour in the auth controller should be a job for the person integrating AshAuthentication, but it quickly became apparent that this was a very common use case. We wound up implementing a system involving a short-lived token which performs the attempted sign-in right in the live-view and then redirects to a new endpoint to set the session on success.

jimsynz

jimsynz

Ash Core Team

Hi @adw632

Thanks for the great feedback. I agree that AshAuthentication constrains folks in some unexpected ways. You’re right that it’s hard for a framework to get right - especially on the first try. Regardless, I’m going to try and address some of the feedback here.

insufficient escape hatches in handling of actions such as implementing password checks

Agreed. We do have this issue open to track changing/removing the password constraints, but if you have ideas for where you’d like to see other escape hatches I’d be keen to hear them.

No sign-in audit records or recording invalid signins, no account lock out after too many failed signins.

This is true, but I’m not 100% convinced that this should be AshAuthentication’s job as it would be fairly easy to implement. That could also be an argument for just doing it. I am definitely open to being convinced. Keen to hear more about what specifically you’d like to see.

Results in security flaws as users should not be able to brute force passwords or tokens unfettered.

Zach and I talked this over at length. There was some discussion of rate-limiting, denylisting, etc, but we couldn’t agree (he is for, I am against) building it into the library. Again this is something that would be fairly easy to implement, but maybe would be more useful as a separate extension?

Lack of control over controller flows, like confirmation and in your case redirects, it’s all concreted up and difficult to reason about.

I disagree on this point. I made the default auth controller/plug as flexible as possible to allow folks to implement the behaviour they want on top of it. As a general rule I didn’t want folks putting authentication in their app without understanding what it was doing, so I left the default behaviour as bare-bones as possible. Turns out I may have been wrong on that because the consistent feedback I’ve had is that people want it to do more for them by default.

Lack of customisation of the UI and view

It’s very customisable - but it turns out not in a very useful way. I expected folks to only use the default liveviews while bootstrapping and then move on to build their own afterwards maybe reusing some of our components. Turns out that’s not the case and they’re being pushed a lot further than I ever imagined. I’m keen to work on generators for these views and even for them to eventually to become the default behaviour.

Use of pow which does not yet officially support liveview sockets

We use assent (which is part of Pow) for our OAuth flows, but that’s it. No other part of Pow is used and OAuth cannot be performed within a liveview, so I’m not sure how this applies.

Inability to add TOTP

There is no inability to add it; just no one has done it yet. The ground work has been done and I can see it being relatively simple to add a new strategy/add-on to support it. See the custom strategy guide for a place to add it. PR’s definitely welcome.

Still requires a lot of touch points on the codebase to implement and what you’re left with is quite inflexible.

As above I don’t think the problem is that AshAuthentication is not flexible enough - it’s just not flexible in the right ways. I’m glad you found a solution that works for you and I’m sorry to read that I nearly scared you away from Ash entirely.

Over all I want to say thanks for the valuable feedback and that there are no sacred cows here. I want to encourage everyone to raise issues, open PR’s or otherwise engage with us to improve the state of the entire ecosystem.

lcabrini

lcabrini OP

Thanks for your reply. Since I posted the original question, I’ve played around quite a bit with it and figured something out that is reasonable for now at least. Takes a bit of work, but that’s fine. Much of it was figuring out how it all works under the hood.

I’m a bit curious about the short-lived token. Where are these stored? In memory? Does it require a token resource? Because I didn’t set one up as the idea for this particular app was users cannot self-register, it’s all done by an admin. Registration is username/password. Users can’t even change their own passwords (the specs of an old system I built many years ago).

In any case, thanks for the great work so far! Elixir, Phoenix and Ash have together managed to make it fun to write code again.

lcabrini

lcabrini OP

It took me a bit of time to figure it all out, I had to jump quite a bit between code and documentation, but once I figured out how the overrides worked and what was available, it was fairly straight-forward. I think maybe it’s a documentation thing more than anything else. I grew up flipping through the Commodore 64 reference manual in search for answers, so I’m used to working that way. Not sure your average modern web developer has that much patience.

Again, there is nothing wrong with provide bare-bones behavior by default IMO, as long as people can figure out how to go about bending it to their own needs. In my case for instance, I pretty much never build your typical “websites” with things like self-registration. I build applications that happen to run in a browser, so an administrator (or in some cases HR officer will create a staff record, which will involve a user account being set up). I need a way to log users in and I need a way for an administrator to perform user management tasks. I’ve cooked something up that works well enough for me for now, but I’m sure there are better ways to do it.

adw632

adw632

Thanks @jimsynz for considering the feedback.

I think part of the experience of using Ash Authentication is that it is often one of the first things we need to think about when building out an app so we come into Ash not knowing it in detail and it’s not obvious how we would change or customise the Authentication view or the controller or replace with our own without digging into the internals of Ash itself. I did see the class overrides for the Ash view but I didn’t see how I could change the layout, order of elements in the view, even add additional elements (like TOTP) along with the password strategy.

I’m glad to hear that a generator approach for liveviews is being considered.

With Pow/Assent I refer to the issue not officially supporting liveview yet, which IMO is not ideal given liveview has been around for some time, it begs the question of that projects ongoing relevance to modern Phoenix apps.

This may sound harsh but having a dependency that is unable to keep up the Phoenix releases is something we have to be very wary about, it’s one of the biggest risks we face that a library is no longer maintained. I’m not saying in this case that Pow Assent isn’t maintained but clearly it’s fallen behind and no-one should indulge a security component that does not officially support liveview if you’re building a liveview app as there can be many edge case that need to be considered.

Happy to provide further advice in respect of handling failed auth attempts, account lock out and recovery and fail2ban type of behaviour for IPs that are attempting brute forcing on auth endpoints be they tokens or passwords.

shamanime

shamanime

Assent, Pow and Pow Assent are different projects.

Pow is the full blown authentication library.

Assent only handles SSO/OAuth request/callback phases and has no dependency on Pow.

Pow Assent glues everything together.

Assent has nothing to do with LiveViews or Controllers etc. Pow’s not full integration with LiveView has no effect on one’s ability to securely use Assent.

adw632

adw632

That may be the case and I don’t really care how pow is carved up, official liveview support is a current gap.

Until liveview is supported officially it is a risk using the Pow or Pow Assent ecosystem within a liveview app.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New

We're in Beta

About us Mission Statement