Closed strazto closed 1 year ago
to begin with, supporting "Sign on with authelia" would look like:
Login Disclaimer:
<a href="https://myjellyfin.example.com/sso/OID/p/authelia" class="raised cancel block emby-button authelia-sso">Sign in with Authelia</a>
Custom CSS code:
/* Make links look like buttons */
a.raised.emby-button {
padding: 0.9em 1em;
color: inherit !important;
}
/* Let disclaimer take full width */
.disclaimerContainer {
display: block;
}
/* Optionally, apply some styling to the `.authelia-sso` class, probably let users configure this */
.authelia-sso {
/* idk set a background image or something lol */
}
I'm planning on restructuring the login flow just a little to accommodate this (as well as solve the issue of when the web frontend is on a different domain than the JF server). The plan is to have everything work as a programmatic API, so instead of returning a webpage, it'll return JSON or something similar and other endpoints can use that API to set cookies or whatever. Then, with this, we can set it so that the button loads some JS that interacts with the API and sets the relevant information instead. The flow would look something like this:
I think it can be simplified at some points. What do you think?
Just putting also my input as I’ve been working hard to implement sso in different services, I’m not sure opening a secondary tab is the best UX in term of sso.
Also, and maybe more important, make sure automatic sso can still be available, either with something similar to the current endpoints, or (and probably better) a configuration point telling the JS script to automatically start the login flow. I’ve contributed something similar (although using headers and not saml/oidc) to ombi.
edit: also, I can try to help once I understand the architecture of JF and the plugins
edit 2: you can probably just skip the polling and: on load check if auth is already done, if yes poll the data and login, if no, and automatic login is implemented or the user clicks a button, start the flow, redirect just as you are doing now, and then when you redirect back to JF, it would reload the script but this time it would be in the logged in branch
So the flow would be something like this:
Ah sorry - I think i mean to reply with my own take on how to approach SSO flow but I must have forgotten to submit the comment.
Basically - it seems that you're implying that we add some custom javascript to the login page that handles some aspects of the flow.
Although this sounds nice, I do not believe there exists an API that would allow a plugin to inject javascript / <script>
elements to arbitrary pages, which would make this challenging.
The webui (correctly) runs DOMPurify
on any user created html, before it's rendered (For example, the login disclaimer).
For now, I'm unsure how to address this, but the new-tab approach should be "good enough" for a while.
For my own reference, here is the setting pattern used to configure loginDisclaimer & branding css:
Get pattern for login disclaimer:
Get pattern for custom css + disclaimer:
Matrix conversation exerpt
Matthew Strasiotto As I understand it, Jellyfin presently doesn't allow plugins to inject JavaScript to any page except their own plugin pages. I'm curious if the Devs would consider allowing plugins to do that? lakerssuperman2 joined the room. Niels What would your use case for such a feature be? Matthew Strasiotto Niels https://github.com/9p4/jellyfin-plugin-sso , for example, js based flows for authenticating with OIDC
GitHub - 9p4/jellyfin-plugin-sso: This plugin allows users to sign in through an SSO provider (such as Google, Microsoft, or your own provider). This enables one-click signin. - GitHub This plugin allows users to sign in through an SSO provider (such as Google, Microsoft, or your own provider). This enables one-click signin. - GitHub - 9p4/jellyfin-plugin-sso: This plugin allows ... Niels I don't think supporting such a thing with js plugins in the frontend is really feasible Matthew Strasiotto what do you mean by that? Niels You want to inject a complete user interface with javascript, that's not going to work when the UI is managed by React. It would also 100% break for every release Matthew Strasiotto I'm aware that it would only apply to the web-ui & web-wrapper apps, but that doesn't bother me as that means that the same client-side plugin code can apply to the same view across like 4 platforms hm, I don't think I'd want to inject a complete UI with JS, it'd be more along the lines of "check headers, perform auth", maybe inject an ivew for a redirect (if that's feasible) i don't actually know how feasible that specific scenario is for OIDC flows in general, I'd need to double check so specifics of that scenario i put forward aside, imagine someone just wants to add a button that performs some action, for example, generates a share link for a file, or triggers an opensubtitle download for the currently viewed item am i right in thinking that there's currently no mechanic within the plugin api to perform these actions? Niels That's not possible no, it would be very difficult to support Matthew Strasiotto ok, fair enough
The ideal option would be to integrate this plugin as part of the official JF spec for better frontend support, but that would be complex to maintain, and I don't know if I can manage that.
In the meantime, web-based auth in conjunction with Quick-Connect should handle 99% of the use-case.
The ideal option would be to integrate this plugin as part of the official JF spec for better frontend support, but that would be complex to maintain, and I don't know if I can manage that.
Yep, the maintainers seem pretty resistant since it would imply that every since client would have to bring its own implementation of OIDC auth
In the meantime, web-based auth in conjunction with Quick-Connect should handle 99% of the use-case.
yeah, when 10.8 gets full-released, pretty much all major clients will have implemented quick-connect
I've implemented an additional button using the method outlined in this issue to automate the SSO login, rather then just lining back to the Server homepage. Specifically, I am hitting the auth proxy redirect URL for Jellyfin. So, if I set "Name of OID Provider" in the Jellyfin's SSO settings to "authentik" the redirect would be /sso/OID/r/authentik
. Anyway, this works great! However, it does launch this URL in a separate tab, which is not ideal.
So, is there any way to configure the button to open in the same tab? I've tried adding target="_self"
to the link.
So, is there any way to configure the button to open in the same tab? I've tried adding
target="_self"
to the link.
It is hardcoded in Jellyfin web interface.
Awww. Bummer. But thanks for the quick answer! Still way better then nothing.
"authentik" the redirect would be
/sso/OID/r/authentik
Did you add the redirect like this to Authentik?
I am still trying to verify if the Authentik/JellyFin integration is working. So any help would be greatly appreciated!
yes that looks correct
Fixed in 076cb1b893711b664386d46f6ee8d776243a9061
Hi, is it possible for the SSO Login button to follow the link in the same tab? href should do that by default, but at least in safari and chrome it always opens in a new tab. Is it possible to overwrite that somehow?
It's hardcoded into the Jellyfin web interface code.
https://github.com/9p4/jellyfin-plugin-sso/issues/16#issuecomment-1591017300
Hi, is it possible for the SSO Login button to follow the link in the same tab? href should do that by default, but at least in safari and chrome it always opens in a new tab. Is it possible to overwrite that somehow?
You can use a form + button to cause the URL to be opened in the current tab. Works well on browsers, although the official Jellyfin app for Android hangs on "Logging in..." when using Authelia.
<form action="https://jellyfin.example.com/sso/OID/start/PROVIDER"><button class="raised button-sso block emby-button" type="submit">Sign In with SSO</button></form>
button.raised.button-sso {
background: #00a4dc;
}
You can use a form + button to cause the URL to be opened in the current tab. Works well on browsers, although the official Jellyfin app for Android hangs on "Logging in..." when using Authelia.
I just tested this with authentik. On IOS it logs in fine, on Android I have the same, hangs at "logging in..."
Thanks for the idea with the form, at least on IOS SSO login seems possible this way (direct SSO without Quickconnect, that option remains, of course).
button.raised.button-sso { background: #00a4dc; }
You are my savior, thank you so much. This makes SSO work in Jellyfin Media Player, which my users have to use because most of my files are HEVC and can't be played on most browsers. Then quick connect will do the trick for the very few that use Kodi with the Jellyfin addon.
If someone finds it useful. There is also a way to directly redirect to SSO if not logged in. Skipping the login-form completely.
I injected JS with nginx:
location /login-redirect.js {
default_type application/javascript;
add_header Content-Disposition "inline; filename=login-redirect.js";
return 200 '
let timer
function isAndroidDevice() {
return /Android/i.test(navigator.userAgent);
}
function checkForSignIn() {
const isLoginPage = window.location.href.includes("login.html")
if (isLoginPage) {
clearInterval(timer)
window.location.href = "/sso/OID/start/authentik"; // Change to your desired URL
}
const isLoggedIn = window.location.href.includes("index.html")
if (isLoggedIn) clearInterval(timer)
}
if (!isAndroidDevice())
timer = setInterval(checkForSignIn, 10);
';
}
Then inside location /web:
sub_filter
'</head>'
'<script plugin="intro-skipper" src="configurationpage?name=skip-intro-button.js"></script>
<script src="/login-redirect.js"></script>
</head>';
It will simply periodically check if the user is at the Jellyfin login url. If yes it will redirect for authentication to SSO. If it detects that the user is at index.html (which is never called when not logged in) it will simply delete the timer.
In my test it even worked in the mobile app. Edit: Only worked in iOS, I simply added code to exclude Android
Originally posted by @matthewstrasiotto in https://github.com/9p4/jellyfin-plugin-sso/issues/2#issuecomment-1103446246
An example - Here, I:
This renders out like so:
"Manual Login" and "Quick Connect" are both builtin by jellyfin, "Forgot Password" is actually my own link to authelia.