Skip to content

feat: Implement SSO Proxy Authentication for music servers (Cloudflare Access, Authelia)#1678

Open
FaKiieZ wants to merge 9 commits intojeffvli:developmentfrom
FaKiieZ:feature/add-cookie-auth-2
Open

feat: Implement SSO Proxy Authentication for music servers (Cloudflare Access, Authelia)#1678
FaKiieZ wants to merge 9 commits intojeffvli:developmentfrom
FaKiieZ:feature/add-cookie-auth-2

Conversation

@FaKiieZ
Copy link
Copy Markdown

@FaKiieZ FaKiieZ commented Feb 9, 2026

I really love feishin. It is such a great music player. The only thing that kept me from using it was, that I expose my music server with a Cloudflare Zero Trust Access proxy. That's the reason why I wanted to implement a dual authentication for feishin. Currently this is only working when using electron. In the Browser, feishin needs to be hosted on the same domain. If not you will have CORS errors because you can't share cookies from a different domain.

Next to the option to add a dual cookie auth for a server, I also added an option in the settings to clear your cookies. With this option it is easy to test the reauthentication flow.

I'm looking forward to your review and would really appreciate to have this functionality in feishin.


I tested this feature on electron with a navidrome server.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
feishin Ready Ready Preview, Comment Mar 20, 2026 6:27pm

@jeffvli
Copy link
Copy Markdown
Owner

jeffvli commented Feb 9, 2026

You can just run pnpm run lint:fix to resolve all linting errors.

@jeffvli
Copy link
Copy Markdown
Owner

jeffvli commented Feb 12, 2026

I may need some time before I review this.

I don't personally run any SSO so I can't immediately test this.

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Feb 12, 2026

I may need some time before I review this.

I don't personally run any SSO so I can't immediately test this.

No worries at all, take your time. I'll continue using and testing my local build of this PR in the meantime.

If it's helpful, Cloudflare Zero Trust provides a relatively simple way to put SSO in front of a site for testing purposes.

@kgarner7
Copy link
Copy Markdown
Collaborator

I don't know what the expected behavior is, but all I see when attempting to use this flow is that I authenticate with my provider in a new window, and then it redirects to Navidrome in that window. Closing said window just results in an error Invalid Navidrome response (String/HTML received), and I can see that none of the auth headers/cookies are used for login.

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Feb 28, 2026

I don't know what the expected behavior is, but all I see when attempting to use this flow is that I authenticate with my provider in a new window, and then it redirects to Navidrome in that window. Closing said window just results in an error Invalid Navidrome response (String/HTML received), and I can see that none of the auth headers/cookies are used for login.

Hey, thanks for testing! Did you test this in the browser or the electron app?

@kgarner7
Copy link
Copy Markdown
Collaborator

I tested it on the electron app. For the browser, I don't actually have this problem, since I can just host Feishin behind the same reverse proxy auth, so it never really knows that it exists.

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Feb 28, 2026

@kgarner7 I've pushed a fix for this! Could you please test again and let me know if this resolves the issue for you?

@kgarner7
Copy link
Copy Markdown
Collaborator

kgarner7 commented Mar 2, 2026

Yes, I pulled it again. I see the cookies actually being sent, but at least for the ND endpoint, I don't see them actually being used. Maybe some hooks are needed for the ndApiClient (and similar endpoints)?

…with global session management and secure Electron login flow.
@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Mar 12, 2026

@kgarner7 You were totally right about the ND endpoint needing hooks! I ended up completely refactoring the features and building a global interceptor that handles it for all of them. The code should now be more focused on the relevant features I wanted to implement.

@anastasia-v-r
Copy link
Copy Markdown

@FaKiieZ Hey there, you seem to be working hard at the very issue plauging me currently (Navidrom + NpmPlus + authelia + Feishin) and im having trouble figuring out how to test out your version of the app. the vercel deployments here dont see to show the options for enabling authelia/sso

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Mar 13, 2026

Hey @anastasia-v-r Thanks for reaching out. I'm really glad you're interested in this and that you're using Authelia! I haven't been able to test this with an Authelia setup myself yet, so your feedback is incredibly valuable to me. 😄

I just added the functionality that was needed to make this feature work in the web version. Currently the easiest way to use the feature in the web version, is to have feishin hosted on the same domain as your music server. Otherwise you must configure your SSO provider to handle CORS and the cookie correctly, which can be a pain.

The recommended way is to use the desktop app version of feishin, because then you won't have any CORS issues.

I hope it will work for you and I'm looking forward to your feedback!

@anastasia-v-r
Copy link
Copy Markdown

anastasia-v-r commented Mar 15, 2026

@FaKiieZ If I understand correctly, this only supports SSO and while thats awesome I just realized I actually use Authelia configured for OTP so I don't believe I can test it. Also, Im actually unsure of how to get docker to build out the webclient container of your specfic branch so i can test it with my config 😅

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Mar 15, 2026

@anastasia-v-r Yes, this feature isn't intended to authenticate your access to Feishin itself. Instead, it’s designed to authenticate you with a music server - primarily via the Feishin desktop app when you're connecting from a different network.

But I think you can actually still test this! Even with OTP, the authentication happens at the proxy level (Authelia). Once you've authenticated there, Feishin simply passes those credentials/headers to your music server. Feishin itself doesn't 'see' the OTP process.

Regarding the Docker build: You can test my branch by cloning it and running docker build -t feishin-sso . inside the folder.

To use the built image, just update your docker-compose.yml to point to the local tag like this:

services:
  feishin:
    image: feishin-sso  # Change this from the official image to your local build
    # ... the rest of your config

Then just run docker compose up -d to restart it with the new code!

@FaKiieZ FaKiieZ changed the title feat: Implement SSO Proxy Authentication (Cloudflare Access, Authelia) feat: Implement SSO Proxy Authentication for music servers (Cloudflare Access, Authelia) Mar 15, 2026
@anastasia-v-r
Copy link
Copy Markdown

@FaKiieZ Alright I've managed to get your container working on a sublocation of a authelia set sub domain proxy host of mine.
https://player.domain.tld - navidrome server
https://player.domain.tld/feishin/ - feishin docker image

Go to feishin sublocation -> enter server details as https://player.domain.tld -> click checkbox -> login redirect works and opens the https://player.domain.tld page which then redirects to my authelia domain https://auth.domain.tld -> sigh in there -> redirect back doesnt work, but im now able to login. I imagine you implemented some stuff in the backend to ensure that feishin can hold onto and pass along those tokens.

the sso redirect page works as well! I'd love to test it on desktop but im not sure how to google to build this application locally. I theres an appimage for it on the Arch user repository but im not sure how to custom build an image using the source repo. My goal is to be able to simply use my navidrome doman protected by authelia with my desktop feishin.

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Mar 20, 2026

@anastasia-v-r Hey thank you for testing this further! Im glad you were able to make it work.

You can download my version of the desktop app all the way at the bottom of the pull request when you open up the section "All checks have passed":
image

There you should see the three entries called something like "Publish (PR) / publish (windows-latest) (pull_request)" and the other two are for ubuntu and macos. Click on either one of them.
image

Then you can navigate to the summary of the action:
image

Here you scroll all the way to the bottom, to the section "Artifacts", where you can download the one that fits your OS:
image

Again, thank you for testing! If you have any other problems, let me know.

@anastasia-v-r
Copy link
Copy Markdown

anastasia-v-r commented Mar 20, 2026

@FaKiieZ When running the desktop version, checking the sso box does cause the popup to open, i was then able to sign into authelia, enter my otp, and be redirected to the audio server, problem. the sso window just keeps opening up the navidrome web ui. it doesnt end up actually connecting. and this is using the same connection settings as the web player version.

image image

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Mar 21, 2026

@anastasia-v-r Since you are using Authelia, according to this guide: https://www.authelia.com/configuration/session/introduction/, you must use authelia_session as your "SSO cookie name" if you haven't configured something else there. Let me know if this works

When the window doesn't close itself, this means the cookie that is needed isn't existing yet. Which means it is either looking for the "wrong" cookie or the wanted cookie is not existing.

@anastasia-v-r
Copy link
Copy Markdown

@FaKiieZ It is configured as you asked and still not working. I am unsure of why but my authelia config surely has the cookies setup correctly

@anastasia-v-r
Copy link
Copy Markdown

@FaKiieZ So in my authelia config ive triple checked and the cookie is indeed set to "authelia_session" and when i set the cookie name directly in the field to also authelia_session it changes from "authentication failed" to "server saved" but never logs in. upon inspecting the network tab of chromium ( shift + ctrl + i ), if i go to "cookies" and the "filtered cookies" there it is. my authelia cookie. just, being ignored for some reason? It also seems per the authelia logs that authelia isnt getting the token hence "Anonymous" for the connection. I ran it side by side (firefox using the feishin docker container as a sublocation under the navidrome url i.e. https://navidrome.domain.tld/feishin/) and it looks like chrome/chromium is ignored/filtering out the cookies which is the why desktop app wont work.

Authelia config

## Session Provider Configuration
##
## The session cookies identify the user once logged in.
## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined.
session:
  ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel.
  ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
  secret: 'CENSORED'

  ## Cookies configures the list of allowed cookie domains for sessions to be created on.
  ## Undefined values will default to the values below.
  cookies:
    -
      ## The name of the session cookie.
      name: 'authelia_session'

      ## The domain to protect.
      ## Note: the Authelia portal must also be in that domain.
      domain: 'domain.tld'

      ## Required. The fully qualified URI of the portal to redirect users to on proxies that support redirections.
      ## Rules:
      ##   - MUST use the secure scheme 'https://'
      ##   - The above 'domain' option MUST either:
      ##      - Match the host portion of this URI.
      ##      - Match the suffix of the host portion when prefixed with '.'.
      authelia_url: 'https://auth.domain.tld'

      ## Optional. The fully qualified URI used as the redirection location if the portal is accessed directly. Not
      ## configuring this option disables the automatic redirection behaviour.
      ##
      ## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication
      ## unless they were redirected to Authelia by the proxy.
      ##
      ## Rules:
      ##   - MUST use the secure scheme 'https://'
      ##   - MUST not match the 'authelia_url' option.
      ##   - The above 'domain' option MUST either:
      ##      - Match the host portion of this URI.
      ##      - Match the suffix of the host portion when prefixed with '.'.
      # default_redirection_url: 'https://www.example.com'

      ## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
      ## Please read https://www.authelia.com/c/session#same_site
      same_site: 'lax'

      ## The value for inactivity, expiration, and remember_me are in seconds or the duration common syntax.
      ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure
      ## because a stolen cookie will last longer giving attackers more time to spy or attack.

      ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user
      ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last
      ## time Authelia detected user activity.
      inactivity: '5 minutes'

      ## The time before the session cookie expires and the session is destroyed if remember me IS NOT selected by the
      ## user.
      expiration: '1 hour'

      ## The time before the cookie expires and the session is destroyed if remember me IS selected by the user. Setting
      ## this value to -1 disables remember me for this session cookie domain. If allowed and the user uses the remember
      ## me checkbox this overrides the expiration option and disables the inactivity option.
      remember_me: '2 weeks'

Authelia Docker Logs (upon a "server saved"

2026-03-26 14:36:39 time="2026-03-26T18:36:39Z" level=info msg="Access to https://player.domain.tld/auth/login (method POST) is not authorized to user   █
<anonymous>, responding with status code 401 with location redirect to                                                                                     █
https://auth.domain.tld/?rd=https%3A%2F%2Fplayer.domain.tld%2Fauth%2Flogin&rm=POST" method=GET path=/api/authz/auth-request remote_ip=172.18.0.9 

@anastasia-v-r
Copy link
Copy Markdown

anastasia-v-r commented Mar 26, 2026

Following up testing between firefox browser, chrome browser, and the app, shows that th 302 request marked "login" on the desktop app, it doesnt send the authelia session cookie at ALL which is why it fails. the request header just, doesnt put the cookie in. on firefox and chrome the original 302 login request shows that in the request headers the cookie is stored marked and sent over ut not in the app when inspecting the network.

More testing. Jeez this is complex. When inputting the correct information. while the cookies arent sent over it ALSO looks like even the payload (user and pass) doesnt get sent over which seems to be apart of why the desktop app is breaking. im getting 0 CORS errors in the network and console and turning on ignore CORS didnt fix anything either.

@FaKiieZ
Copy link
Copy Markdown
Author

FaKiieZ commented Mar 30, 2026

@anastasia-v-r I will have to try this out with Authelia myself. I'm using Cloudflare Zero Trust Access and for me it works. I have to look deeper into this issue, but currently I'm not having too much time because of dues in school and also work. It will probably take 3 weeks and then I should have a little bit more time, I'm sorry. And thank you very much for your intense testing!

@anastasia-v-r
Copy link
Copy Markdown

@FaKiieZ No problem! You're doing this for free on your own time so its alright! I did more research and it seems that if we can simple manually stuff the tokens into the header in the src/main section then that should bypass the whole wierd CORS issues that pop up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants