amarandon

amarandon

Sharing authentication session with another app

Hello Elixir Forum !

I have an existing web app that I’d like to integrate within a new phoenix project. To provide context for those who might be familiar with it, that other app is JupyterHub, a multi-user server for the popular Jupyter data-science platform. But what I’m going to describe shouldn’t be specific to that particular app. In a way what I’m trying to achieve is the inverse of this : PASETO vs JOSE (JWT - JSON Web Tokens) (protocols/standards for managing user sessions) - #9 by idi527 I want to manage user accounts and login in my phoenix app and have my users be logged in automatically to the third party app.
I figured out how to control the login/logout process within the third-party app. It’s quite flexible, it could be based on calling an external service or on parsing a cookie. Both apps will be served under the same domain so it’s possible to share cookies between the two. In fact I managed to hack something together using Guardian and JWT. I works like this:

While it seems to be working, I’m not really happy with this solutions for a few reasons:

  1. there are security concerns with using JWT for authentication which I don’t fully understand
  2. JWT wasn’t designed for authentication in the first place, as mentioned several times in this forum by @OvermindDL1 and others
  3. it bothers me to transfer information (the user id) that I don’t really need to give to the user agent, even if it’s a signed cookie that in theory cannot be tampered with (we all know that cryptography sometimes end up being broken)

Ideally, I’d like to share only a session id between both apps. The third party app would receive that session id via a cookie that can be shared between both apps since they’re both on the same domain. The third party app would issue a request in the background to a protected endpoint of the phoenix app. That endpoint would return user information to the third party app, which would use that information to log the user in. Here is a diagram of the workflow I’m thinking of:

What do you think of this plan so far ?

I’m currently trying to implement something based on Phauxth, which seems to be simpler and easier to understand that Guardian. Now I’m trying to figure out I can implement the endpoint that takes a session cookie and returns user information. It seems to be a triple of dot-separated, base64-encoded strings, but not quite, as decoding its parts with Base.decode64/1 gives me an :error. Decoding it with GNU coreutils’ base64 program gives me this:

tm
  _csrf_tokenmcopw6CzJhZ+ZoPsm6jW9Dw==mphauxth_session_idmF94xYayLj2Ff17Aiw4base64: invalid input

Once I’ll have figured out the exact format of this cookie, I suppose I can retrieve the phauxth session and extract user info. So if you have more info about how the session cookie works, that would probably help me. I tried reading Plug’s source code but got a bit lost.

Edit: I found that the ETS session storage allows to retrieve the session data easily given just the session ID. I understand the drawbacks of this storage and I’m thinking of implementing a custom session storage for my PostgreSQL database.

Most Liked

alexandrubagu

alexandrubagu

If you want to archive the solution described above I think you can read or implement the OAuth2 RFC. Also if the app internally you can stick with SSO ( based on ip / LDAP )

I found this an elixir implementation for this: GitHub - ueberauth/oauth2: An Elixir OAuth 2.0 Client Library · GitHub maybe will help you.

OvermindDL1

OvermindDL1

They are reuseable within their active time period unless you store invalidation data on the server, which if you are doing that then there is no point in JWT to begin with. :slight_smile:

It’s good for database-less purely time-based non-invalidateable authorization, not authentication. :slight_smile:

If the apps share a backend, just pass a signed ID.
If the apps don’t share a backend but share signing keys, then use a token.
Else this might be a good case for JWT (transferring data safely between servers that have no connections between each other), though they’ll need each others public keys to verify the signature.

Oh that’s just a lot easier then, just make sure they share the same signing key for the cookie and good to go (or put in unsigned data if tampering is not an issue).

Actually what it looks like to me that you are trying to create is an SSO/OAuth/Etc server authentication, why not just use those standards?

Oh hey, yes this!

Just follow the spec and use existing libraries for it. :slight_smile:

amarandon

amarandon

Thank you both for your replies!

From what I understand, OAuth was also designed to handle authorization, not authentication. Some have bended it to handle authentication by providing an authorized “user info” resource and this has even given birth to OpenID Connect, a standard on top of OAuth that is explicitly designed for authentication and which makes use of … JWT!

This is all very confusing and is nothing specific to Elixir or Phoenix so i shall not bother this forum more with this question. My problem of accessing session data is solved by the ETS session storage backend, which I may replace with a custom SQL-based backend later on.

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement