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?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 10 of 17 Posts
lcabrini
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
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:
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
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
Hi @lcabrini
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 tokenwhich performs the attempted sign-in right in the live-view and then redirects to a new endpoint to set the session on success.jimsynz
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.
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.
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.
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?
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.
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.
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.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.
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
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
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
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
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
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.