Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jellyfin only allows specific characters in username, SSO provider can send special characters #199

Open
qrkourier opened this issue Jul 6, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@qrkourier
Copy link

Describe the bug
Successful authN results in error while creating Jellyfin user because the username contains a pipe | character. I encountered the same issue with several OpenID Connect providers through Auth0: Google, Microsoft, Amazon, and Apple.

To Reproduce

  1. In Auth0, create an application for Jellyfin and enable at least one social connection, e.g., Google
  2. In Jellyfin, create a provider for Auth0
  3. In Jellyfin, visit the SSO start page to be redirected to OIDC provider (Auth0 app entrypoint domain)
  4. Authenticate with any OIDC provider to be redirected to the Jellyfin SSO callback, e.g., /sso/OID/redirect/auth0
  5. Note the SSO errors in Jellyfin log

Expected behavior
I expected the Jellyfin user to be created with preferred_username claim

Configuration

<?xml version="1.0" encoding="utf-8"?>
<ServerConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <LogFileRetentionDays>3</LogFileRetentionDays>
  <IsStartupWizardCompleted>true</IsStartupWizardCompleted>
  <CachePath>/cache</CachePath>
  <EnableMetrics>false</EnableMetrics>
  <EnableNormalizedItemByNameIds>true</EnableNormalizedItemByNameIds>
  <IsPortAuthorized>true</IsPortAuthorized>
  <QuickConnectAvailable>true</QuickConnectAvailable>
  <EnableCaseSensitiveItemIds>true</EnableCaseSensitiveItemIds>
  <DisableLiveTvChannelUserDataName>true</DisableLiveTvChannelUserDataName>
  <MetadataPath>/config/metadata</MetadataPath>
  <MetadataNetworkPath />
  <PreferredMetadataLanguage>en</PreferredMetadataLanguage>
  <MetadataCountryCode>US</MetadataCountryCode>
  <SortReplaceCharacters>
    <string>.</string>
    <string>+</string>
    <string>%</string>
  </SortReplaceCharacters>
  <SortRemoveCharacters>
    <string>,</string>
    <string>&amp;</string>
    <string>-</string>
    <string>{</string>
    <string>}</string>
    <string>'</string>
  </SortRemoveCharacters>
  <SortRemoveWords>
    <string>the</string>
    <string>a</string>
    <string>an</string>
  </SortRemoveWords>
  <MinResumePct>5</MinResumePct>
  <MaxResumePct>90</MaxResumePct>
  <MinResumeDurationSeconds>300</MinResumeDurationSeconds>
  <MinAudiobookResume>5</MinAudiobookResume>
  <MaxAudiobookResume>5</MaxAudiobookResume>
  <InactiveSessionThreshold>0</InactiveSessionThreshold>
  <LibraryMonitorDelay>60</LibraryMonitorDelay>
  <LibraryUpdateDuration>30</LibraryUpdateDuration>
  <ImageSavingConvention>Legacy</ImageSavingConvention>
  <MetadataOptions>
    <MetadataOptions>
      <ItemType>Book</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers />
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>Movie</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers />
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>MusicVideo</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers>
        <string>The Open Movie Database</string>
      </DisabledMetadataFetchers>
      <MetadataFetcherOrder />
      <DisabledImageFetchers>
        <string>The Open Movie Database</string>
      </DisabledImageFetchers>
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>Series</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers />
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>MusicAlbum</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers>
        <string>TheAudioDB</string>
      </DisabledMetadataFetchers>
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>MusicArtist</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers>
        <string>TheAudioDB</string>
      </DisabledMetadataFetchers>
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>BoxSet</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers />
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>Season</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers />
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
    <MetadataOptions>
      <ItemType>Episode</ItemType>
      <DisabledMetadataSavers />
      <LocalMetadataReaderOrder />
      <DisabledMetadataFetchers />
      <MetadataFetcherOrder />
      <DisabledImageFetchers />
      <ImageFetcherOrder />
    </MetadataOptions>
  </MetadataOptions>
  <SkipDeserializationForBasicTypes>true</SkipDeserializationForBasicTypes>
  <ServerName>Autumnvale</ServerName>
  <UICulture>en-US</UICulture>
  <SaveMetadataHidden>false</SaveMetadataHidden>
  <ContentTypes />
  <RemoteClientBitrateLimit>0</RemoteClientBitrateLimit>
  <EnableFolderView>false</EnableFolderView>
  <EnableGroupingIntoCollections>false</EnableGroupingIntoCollections>
  <DisplaySpecialsWithinSeasons>true</DisplaySpecialsWithinSeasons>
  <CodecsUsed />
  <PluginRepositories>
    <RepositoryInfo>
      <Name>Jellyfin Stable</Name>
      <Url>https://repo.jellyfin.org/files/plugin/manifest.json</Url>
      <Enabled>true</Enabled>
    </RepositoryInfo>
    <RepositoryInfo>
      <Name>jellyfin-plugin-sso</Name>
      <Url>https://raw.githubusercontent.com/9p4/jellyfin-plugin-sso/manifest-release/manifest.json</Url>
      <Enabled>true</Enabled>
    </RepositoryInfo>
  </PluginRepositories>
  <EnableExternalContentInSuggestions>true</EnableExternalContentInSuggestions>
  <ImageExtractionTimeoutMs>0</ImageExtractionTimeoutMs>
  <PathSubstitutions />
  <EnableSlowResponseWarning>true</EnableSlowResponseWarning>
  <SlowResponseThresholdMs>500</SlowResponseThresholdMs>
  <CorsHosts>
    <string>*</string>
  </CorsHosts>
  <ActivityLogRetentionDays>30</ActivityLogRetentionDays>
  <LibraryScanFanoutConcurrency>0</LibraryScanFanoutConcurrency>
  <LibraryMetadataRefreshConcurrency>0</LibraryMetadataRefreshConcurrency>
  <RemoveOldPlugins>false</RemoveOldPlugins>
  <AllowClientLogUpload>true</AllowClientLogUpload>
  <DummyChapterDuration>0</DummyChapterDuration>
  <ChapterImageResolution>MatchSource</ChapterImageResolution>
  <ParallelImageEncodingLimit>0</ParallelImageEncodingLimit>
  <CastReceiverApplications>
    <CastReceiverApplication>
      <Id>F007D354</Id>
      <Name>Stable</Name>
    </CastReceiverApplication>
    <CastReceiverApplication>
      <Id>6F511C87</Id>
      <Name>Unstable</Name>
    </CastReceiverApplication>
  </CastReceiverApplications>
  <TrickplayOptions>
    <EnableHwAcceleration>false</EnableHwAcceleration>
    <EnableHwEncoding>false</EnableHwEncoding>
    <ScanBehavior>NonBlocking</ScanBehavior>
    <ProcessPriority>BelowNormal</ProcessPriority>
    <Interval>10000</Interval>
    <WidthResolutions>
      <int>320</int>
    </WidthResolutions>
    <TileWidth>10</TileWidth>
    <TileHeight>10</TileHeight>
    <Qscale>4</Qscale>
    <JpegQuality>90</JpegQuality>
    <ProcessThreads>1</ProcessThreads>
  </TrickplayOptions>
</ServerConfiguration>

Versions (please complete the following information):

  • OS: [e.g. Linux]
  • Browser: [e.g. chrome, safari]
  • Jellyfin Version: 10.9.7
  • Plugin Version: 3.5.2.4

Additional context

jellyfin  | [19:32:48] [INF] [52] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO user google-oauth2|{redacted numeric google account id} doesn't exist, creating...
jellyfin  | [19:32:48] [ERR] [52] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL POST /sso/OID/Auth/auth0.
jellyfin  | System.ArgumentException: Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) (Parameter 'name')
jellyfin  |    at Jellyfin.Server.Implementations.Users.UserManager.ThrowIfInvalidUsername(String name)
jellyfin  |    at Jellyfin.Server.Implementations.Users.UserManager.CreateUserAsync(String name)
jellyfin  |    at Jellyfin.Plugin.SSO_Auth.Api.SSOController.CreateCanonicalLinkAndUserIfNotExist(String mode, String provider, String canonicalName)
jellyfin  |    at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidAuth(String provider, AuthResponse response)
@qrkourier qrkourier added the bug Something isn't working label Jul 6, 2024
@9p4
Copy link
Owner

9p4 commented Jul 17, 2024

I guess I'll have to add a stripping option in the username generation, but that may cause some security issues with similar but different usernames. Maybe the stripping will remain an opt-in feature.

In the meantime, could you set the username claim field to be "sub" or something?

@qrkourier
Copy link
Author

Possibly so! I'm learning how to OpenID Connect and gaining familiarity with claims. Tokens obtained via Auth0 for Google, Microsoft, Amazon, and Apple do have an email claim, and it's the sub claim that contains the pipe | character. It might be sufficient for (most) IdP to configure the Jellyfin SSO plugin to use email. Perhaps I overlooked a step or option in the configuration. I understand things slightly better now than at the time I raised the bug report.

Facebook requires progressive profiling, at least in certain cases, it seems. When I authenticate to FB via Auth0 I never get an email claim in the token, only sub, and yet others have been unable to reproduce this, saying they are
able to get an email claim from FB. 🤷 I reasoned it could be because I had restricted email sharing in my FB privacy settings, but I can reproduce it with those relaxed and with a separate test account without any restrictions. It remains a mystery. Here's the Immich issue where I was investigating and documenting the FB via Auth0 issue.

Still, getting this working with Auth0 for Google, Microsoft, Amazon, and Apple would be plenty of login options for my case, so I'm not too hung up on getting Facebook working.

@9p4 9p4 changed the title create user fails - numeric id with pipe character is not a valid username Jellyfin only allows specific characters in username, SSO provider can send special characters Aug 19, 2024
@9p4
Copy link
Owner

9p4 commented Aug 19, 2024

See #204 (comment) for more context

@9p4 9p4 pinned this issue Aug 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants