jellyfin-plugin-ldapauth icon indicating copy to clipboard operation
jellyfin-plugin-ldapauth copied to clipboard

Cannot save settings

Open flowbe opened this issue 4 years ago • 21 comments

I installed the LDAP Authentication extension in Jellyfin and I am not able to save the settings. When I try to edit the settings, the page simply reloads without my saving my changes.

I am on Jellyfin 10.6.4 and LDAP-Auth 9.0.0.0.

I saw that there is a similar issue in the Jellyfin repo (https://github.com/jellyfin/jellyfin/issues/3798) but the issue still hasn't been fixed. Is there any workaround to this problem?

flowbe avatar Oct 13 '20 00:10 flowbe

It’s a bug with web, just try saving again after it automatically refreshes

crobibero avatar Oct 13 '20 01:10 crobibero

Thanks, the workaround works, I hope this will be fixed soon.

flowbe avatar Oct 13 '20 03:10 flowbe

I have the same issue except at a different stage. The config I enter does write a file in ./plugins/configuration/LDAP-Auth.xml but when I restart the container it's gone! Well, not exactly, it seems to go in snippets, if you will.

I restart the container and from SSH I'm checking the mapped location for the config

  1. I save the changes
  2. Verify that the file is there through SSH
  3. Restart the container – keep checking for the file and catting its contents – all there
  4. Web UI returns, log in with the master admin account go str8 to LDAP settings – they've been reset to defaults
  5. Check if file exists in datastore, yes. Contents checks out? Yes.
  6. Finally attempt to login with directory account 6.1 Log goes crazy:

[11:07:20] [ERR] [39] Jellyfin.Plugin.LDAP_Auth.LdapAuthenticationProviderPlugin: Failed to Connect or Bind to server System.AggregateException: One or more errors occurred. (Name or service not known) ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known at System.Net.Dns.InternalGetHostByName(String hostName) at System.Net.Dns.ResolveCallback(Object context) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source) at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult) at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult) at System.Net.Dns.<>c.<GetHostAddressesAsync>b__25_1(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Novell.Directory.Ldap.Connection.Connect(String host, Int32 port, Int32 semaphoreId) at Novell.Directory.Ldap.LdapConnection.Connect(String host, Int32 port) at Jellyfin.Plugin.LDAP_Auth.LdapAuthenticationProviderPlugin.LocateLdapUser(String username) [11:07:20] [ERR] [39] Jellyfin.Server.Implementations.Users.UserManager: Error authenticating with provider LDAP-Authentication MediaBrowser.Controller.Authentication.AuthenticationException: Failed to Connect or Bind to server at Jellyfin.Plugin.LDAP_Auth.LdapAuthenticationProviderPlugin.LocateLdapUser(String username) at Jellyfin.Plugin.LDAP_Auth.LdapAuthenticationProviderPlugin.Authenticate(String username, String password) at Jellyfin.Server.Implementations.Users.UserManager.AuthenticateWithProvider(IAuthenticationProvider provider, String username, String password, User resolvedUser) [11:07:20] [ERR] [39] Jellyfin.Server.Implementations.Users.UserManager: Error authenticating with provider Default MediaBrowser.Controller.Authentication.AuthenticationException: Specified user does not exist. at Jellyfin.Server.Implementations.Users.DefaultAuthenticationProvider.Authenticate(String username, String password, User resolvedUser) at Jellyfin.Server.Implementations.Users.UserManager.AuthenticateWithProvider(IAuthenticationProvider provider, String username, String password, User resolvedUser) [11:07:20] [ERR] [39] Jellyfin.Server.Implementations.Users.UserManager: Error authenticating with provider InvalidOrMissingAuthenticationProvider MediaBrowser.Controller.Authentication.AuthenticationException: User Account cannot login with this provider. The Normal provider for this user cannot be found at Jellyfin.Server.Implementations.Users.InvalidAuthProvider.Authenticate(String username, String password) at Jellyfin.Server.Implementations.Users.UserManager.AuthenticateWithProvider(IAuthenticationProvider provider, String username, String password, User resolvedUser) [11:07:20] [INF] [39] Jellyfin.Server.Implementations.Users.UserManager: Authentication request for v has been denied (IP: 2001:db8:33:9::32). [11:07:20] [ERR] [39] Emby.Server.Implementations.HttpServer.HttpListenerHost: Error processing request: Invalid username or password entered. URL: https://play.domain.tld/Users/authenticatebyname

  1. Config file and its data are still there.

root@zx2:/mnt/disks/zx1_nfs_containerbridge/jellyfin/plugins/configurations# ls -l total 5 -rw-r--r-- 1 root users 1101 Nov 5 10:52 LDAP-Auth.xml

  1. [and] Permissions match those of the main config file's:

root@zx2:/mnt/disks/zx1_nfs_containerbridge/jellyfin# ls -l config/ total 19 drwxr-xr-x 4 root users 4 Nov 5 09:38 dlna/ -rw-r--r-- 1 root users 933 Nov 5 10:59 encoding.xml -rw-r--r-- 1 root users 1362 Nov 5 09:38 logging.default.json -rw-r--r-- 1 root users 1333 Nov 5 09:38 migrations.xml -rw-r--r-- 1 root users 6309 Nov 5 10:21 system.xml

vitaprimo avatar Nov 05 '20 18:11 vitaprimo

Workaround does not seem to help in my case, is there some other way of getting this to work?

mjog avatar Nov 15 '20 09:11 mjog

Any Updates here?

LukasK13 avatar Dec 09 '20 21:12 LukasK13

I just tested with Jellyfin 10.7rc1, LDAP v10; and I can still not replicate the issue. As I mentioned previously- attempting to save will cause the page to refresh the first time, but will save properly the second time.

crobibero avatar Dec 10 '20 20:12 crobibero

I did not know it will be fixed in 10.7. The issue occurs on 10.6 with LDAP v9. Saving a second time did not fix the issue for me. I had to create the XML file manually

LukasK13 avatar Dec 10 '20 20:12 LukasK13

I have just tried to install the v10 through the plugin section according to comment https://github.com/jellyfin/jellyfin/issues/3798#issuecomment-742776788

While trying to install the plugin through the jellyfin UI, I have a 404 error that I do not have with v9, how do you guys recommend to install the v10, when will the v10 latest will be really available?

kopax avatar Dec 10 '20 21:12 kopax

Did you use 10.7 or 10.6? v10 is for 10.7 only.

LukasK13 avatar Dec 10 '20 22:12 LukasK13

v10 is for jellyfin 10.7rc1 I was not able to reproduce the issue with v9 for jellyfin 10.6 either

crobibero avatar Dec 10 '20 22:12 crobibero

Sorry for bringing this up late: I'm using a new install of 10.6 with docker. Does this change anything?

LukasK13 avatar Dec 10 '20 22:12 LukasK13

That's exactly how I have my system set up, so it should still work

crobibero avatar Dec 10 '20 22:12 crobibero

which information or logging would help you to reproduce the issue?

LukasK13 avatar Dec 10 '20 22:12 LukasK13

Did you use 10.7 or 10.6? v10 is for 10.7 only.

I am using Version: 10.6.4, I have tried to upgrade the image to linuxserver/jellyfin:latest in Docker hub, no matter what I do, the jellyfin version that runs is 10.6.4.

You can search here for 10.7, there's no results,

How did you guys upgrade to 10.7 ?

kopax avatar Dec 11 '20 14:12 kopax

That's exactly how I have my system set up, so it should still work

I am retrying with v9 and as you said, I was able to save the settings after submitting once, but then, I am trying to edit more and more, remove settings, and saving keep not saving. I am not able to set the proper settings despite I am submitting an infinite amount of time.

Edit

After many attempt of displaying the form, I successfully manage to configure the ldap client and save the settings, I keep not being able to authenticate using ldap users using v9.

kopax avatar Dec 11 '20 14:12 kopax

Jellyfin 10.7 is currently in RC1, and available in the official container image jellyfin/jellyfin:10.7.0-rc1

oddstr13 avatar Dec 11 '20 18:12 oddstr13

That makes sens, I am using linuxserver because they have a better handling of uuid/guid in general, I have not tried the official image and I am afraid to break the things up by switching. I presume I'll have to wait until this is released on linuxserver.

Thanks!

kopax avatar Dec 11 '20 18:12 kopax

I am using Jeelyfin 10.6.4 and LDAP plugin version 9.0.0.0

Saving plugin properties always refresh the page and nothing is saved.

I compared with the AudioDB configuration page which contains the following script


            var PluginConfig = {
                pluginId: "a629c0da-fac5-4c7e-931a-7174223f14c8"
            };

            document.querySelector('.configPage')
                .addEventListener('pageshow', function () {
                    Dashboard.showLoadingMsg();
                    ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
                        document.querySelector('#enable').checked = config.Enable;
                        document.querySelector('#replaceAlbumName').checked = config.ReplaceAlbumName;
    
                        Dashboard.hideLoadingMsg();
                    });
                });

            document.querySelector('.configForm')
                .addEventListener('submit', function (e) {
                    Dashboard.showLoadingMsg();
    
                    ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
                        config.Enable = document.querySelector('#enable').checked;
                        config.ReplaceAlbumName = document.querySelector('#replaceAlbumName').checked;
    
                        ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
                    });
                    
                    e.preventDefault();
                    return false;
                });

But for the LDAP plugin, the script is the following


            var LdapConfigurationPage = {
                pluginUniqueId: "958aad66-3784-4d2a-b89a-a7b6fab6e25c",
                
                txtLdapServer: document.getElementById("txtLdapServer"),
                chkUseSsl: document.getElementById("chkUseSsl"),
                chkUseStartTls: document.getElementById("chkUseStartTls"),
                chkSkipSslVerify: document.getElementById("chkSkipSslVerify"),
                txtLdapBaseDn: document.getElementById("txtLdapBaseDn"),
                txtLdapPort: document.getElementById("txtLdapPort"),
                txtLdapSearchAttributes: document.getElementById("txtLdapSearchAttributes"),
                txtLdapUsernameAttribute: document.getElementById("txtLdapUsernameAttribute"),
                txtLdapSearchFilter: document.getElementById("txtLdapSearchFilter"),
                txtLdapAdminFilter: document.getElementById("txtLdapAdminFilter"),
                txtLdapBindUser: document.getElementById("txtLdapBindUser"),
                txtLdapBindPassword: document.getElementById("txtLdapBindPassword"),
                chkEnableUserCreation: document.getElementById("chkEnableUserCreation")
            };

            window.addEventListener("pageshow", function (_) {
                Dashboard.showLoadingMsg();

                ApiClient.getPluginConfiguration(LdapConfigurationPage.pluginUniqueId).then(function (config) {
                    LdapConfigurationPage.txtLdapServer.value = config.LdapServer || "ldap-server.contoso.com"; 
                    LdapConfigurationPage.chkUseSsl.checked = config.UseSsl;
                    LdapConfigurationPage.chkUseStartTls.checked = config.UseStartTls;
                    LdapConfigurationPage.chkSkipSslVerify.checked = config.SkipSslVerify;
                    LdapConfigurationPage.txtLdapBaseDn.value = config.LdapBaseDn || "o=domains,dc=contoso,dc=com";
                    LdapConfigurationPage.txtLdapPort.value = config.LdapPort || "389";
                    LdapConfigurationPage.txtLdapSearchAttributes.value = config.LdapSearchAttributes || "uid, cn, mail, displayName";
                    LdapConfigurationPage.txtLdapUsernameAttribute.value = config.LdapUsernameAttribute || "uid"; 
                    LdapConfigurationPage.txtLdapSearchFilter.value = config.LdapSearchFilter || "(memberOf=CN=JellyfinUsers,DC=contoso,DC=com)"; 
                    LdapConfigurationPage.txtLdapAdminFilter.value = config.LdapAdminFilter || "(enabledService=JellyfinAdministrator)";
                    LdapConfigurationPage.txtLdapBindUser.value = config.LdapBindUser || "CN=BindUser,DC=contoso,DC=com";
                    LdapConfigurationPage.txtLdapBindPassword.value = config.LdapBindPassword || "";
                    LdapConfigurationPage.chkEnableUserCreation.checked = config.CreateUsersFromLdap;
                    Dashboard.hideLoadingMsg();
                });
            });

            document.querySelector(".esqConfigurationForm").addEventListener("submit", function(e){
                Dashboard.showLoadingMsg();

                ApiClient.getPluginConfiguration(LdapConfigurationPage.pluginUniqueId).then(function (config) {
                    config.LDAPServer = LdapConfigurationPage.txtLdapServer.value;
                    config.UseSsl = LdapConfigurationPage.chkUseSsl.checked;
                    config.UseStartTls = LdapConfigurationPage.chkUseStartTls.checked;
                    config.SkipSslVerify = LdapConfigurationPage.chkSkipSslVerify.checked;
                    config.LdapBaseDn = LdapConfigurationPage.txtLdapBaseDn.value;
                    config.LdapPort = parseInt(LdapConfigurationPage.txtLdapPort.value || "389");
                    config.LdapSearchAttributes = LdapConfigurationPage.txtLdapSearchAttributes.value;
                    config.LdapUsernameAttribute = LdapConfigurationPage.txtLdapUsernameAttribute.value;
                    config.LdapSearchFilter = LdapConfigurationPage.txtLdapSearchFilter.value;
                    config.LdapAdminFilter = LdapConfigurationPage.txtLdapAdminFilter.value;
                    config.LdapBindUser = LdapConfigurationPage.txtLdapBindUser.value;
                    config.LdapBindPassword = LdapConfigurationPage.txtLdapBindPassword.value;
                    config.CreateUsersFromLdap = LdapConfigurationPage.chkEnableUserCreation.checked;

                    ApiClient.updatePluginConfiguration(LdapConfigurationPage.pluginUniqueId, config).then(Dashboard.processPluginConfigurationUpdateResult);
                    e.preventDefault();
                });

                // Disable default form submission
                return false;
            });

As you can notice, the e.preventDefault for LDAP plugin is inside the event listener. For AudioDB, this instruction is outside, just before the false return.

May be this is the cause of the error ?

I finally managed to make it works. First, I use brower developer tool to trak all HTTP request. Then I go to the AudioDB plugin settings and made a change to track the request. It is something like this

curl 'http://192.168.1.32:8096/Plugins/a629c0da-fac5-4c7e-931a-7174223f14c8/Configuration' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Cache-Control: no-cache' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36' \
  -H 'X-Emby-Authorization: MediaBrowser Client="Jellyfin Web", Device="Chrome", DeviceId="TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzg4LjAuNDMyNC4xNTAgU2FmYXJpLzUzNy4zNnwxNjEyNjMzNDAxNjYz", Version="10.6.4", Token="9c1021baa8364234bcefc8750814881c"' \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'Origin: http://192.168.1.32:8096' \
  -H 'Referer: http://192.168.1.32:8096/web/index.html?' \
  -H 'Accept-Language: en,fr;q=0.9,en-US;q=0.8' \
  --data-raw '{"Enable":true,"ReplaceAlbumName":false}' \
  --compressed \
  --insecure

It did something similar with LDAP plugin to retrieve the plugin ID : 958aad66-3784-4d2a-b89a-a7b6fab6e25c And then I built the curl request with the expected payload for the LDAP configuration

curl 'http://192.168.1.32:8096/Plugins/958aad66-3784-4d2a-b89a-a7b6fab6e25c/Configuration' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Cache-Control: no-cache' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36' \
  -H 'X-Emby-Authorization: MediaBrowser Client="Jellyfin Web", Device="Chrome", DeviceId="TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzg4LjAuNDMyNC4xNTAgU2FmYXJpLzUzNy4zNnwxNjEyNjMzNDAxNjYz", Version="10.6.4", Token="9c1021baa8364234bcefc8750814881c"' \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*' \
  -H 'Origin: http://192.168.1.32:8096' \
  -H 'Referer: http://192.168.1.32:8096/web/index.html?' \
  -H 'Accept-Language: en,fr;q=0.9,en-US;q=0.8' \
  --data-raw '{"LdapServer":"LDAP SERVER NAME","LdapBaseDn":"BASE DN","LdapPort":true,LdapSearchAttributes:"uid, cn, mail, displayName","LdapUsernameAttribute":"uid","LdapSearchFilter":"LDAP SEARCH FILTER","LdapAdminFilter":"LDAP ADMIN FILTER","LdapBindUser":"BIND DN","LdapBindPassword":"BIND PASSWORD","CreateUsersFromLdap":true,"UseSsl":false,"UseStartTls":false,"SkipSslVerify":false}' \
  --compressed \
  --insecure

Replace LDAP SERVER NAME, BASE DN, LDAP SEARCH FILTER, LDAP ADMIN FILTER, BIND DN and BIND PASSWORD with expected values. The curl cmmand is successfull and the configuration is correctly saved. For installation on Ubuntu, location is /var/lib/jellyfin/plugins/configurations/LDAP-Auth.xml

Carefull, the server name MUST be a real server name. When I used localhost, it did not work.

A strange behavious was noted, when the configuration file exists, updating values frmo the page seems to work.

ejouvin avatar Feb 07 '21 13:02 ejouvin

I was having the same issue regardless of the second save.

Jellyfin 10.6.4. LDAP 9.0 jellyfin/jellyfin:latest image Running on Synology DS918+

I noticed that the configuration file was not being created regardless of how many times I saved. I went to plugins/configurations and did

touch LDAP-Auth.xml

Made sure that the permissions of the file were the same as the docker container. Did a save in the web with the default info and it populated the LDAP-Auth.xml. I then edited the XML file with my settings and did a restart of jellyfin. Now the plugin page for LDAP is showing the settings from the file and saving changes from the web work. Guessing some kind of permissions to write to the directory but did not investigate further.

kernelkaribou avatar Feb 17 '21 21:02 kernelkaribou

Running Jellyfin 10.8.10 and LDAP 17.0.0.0 and I still seem to be experiencing this issue.

Unfortunately, touching the LDAP-Auth.xml file does not seem to work. Other plugins seem to save their settings fine, shouldn't be a me issue.

Rojikku avatar Jun 03 '23 16:06 Rojikku

Actually I was able to work around this. In my case, I am using kubernetes. The app automatically is hosted up on a URL, and redirected through cloudflare, and it's a whole thing. For some reason, that prevents this plugin from displaying correctly. I did a port forward, accessed the interface via localhost, and it worked fine.

Rojikku avatar Jun 03 '23 17:06 Rojikku