Compare commits

...

12 Commits

Author SHA1 Message Date
Ersei Saggi 42fba8656a Make CI happy 2024-05-13 09:32:52 -04:00
Ersei Saggi 618bcdbd8a Update GH workflows to use net8.0 2024-05-13 09:31:05 -04:00
Ersei Saggi 2e8c19d631 Update for Jellyfin 10.9 2024-05-13 09:17:42 -04:00
9p4 19a6b49afa Merge pull request #190 from tbelway/main
Update providers.md to include android app keycloak OIDC redirect URI
2024-05-13 08:31:54 -04:00
tbelway 5b26808f0e Update providers.md to include android app keycloak redirect URI 2024-05-12 20:24:20 -04:00
9p4 2724d64de8 Merge pull request #170 from hendrik1120/main
update authelia example to authelia v4.38
2024-03-14 16:40:11 -04:00
Hendrik Sievers 63ec46db4a keep authelia example configuration prior to v4.38 2024-03-14 21:29:49 +01:00
Hendrik Sievers 4c891d8ef0 update authelia example to authelia v4.38
fix warnings in authelia
fix authelia using client_secret_basic instead of client_secret_post
2024-03-14 20:50:39 +01:00
Jade Lovelace 29189a9af0 Update version in SSO-Auth.csproj 2024-02-22 20:23:49 -05:00
Ersei Saggi 3894048168 Prepare for v3.5.2.3 2024-02-21 17:09:51 -05:00
Ersei Saggi d51e5069d6 feat: allow for better endpoint validation 2024-02-20 09:11:48 -05:00
Sergii Bogomolov 5149cef625 Remove jellyfin_credentials before loading iframe
Due to Safari's aggressive caching updated jellyfin_credentials were not
used. They were overwritten with the old credentials instead. This fix
removes jellyfin_credentials first, then let's iframe load and create
new jellyfin_credentials with no access token. After this we update it
and login succeeds.
2024-02-10 13:09:05 -05:00
13 changed files with 135 additions and 98 deletions
+3 -3
View File
@@ -3,12 +3,12 @@ on:
inputs:
dotnet-version:
required: false
default: "6.0.x"
default: "8.0.x"
description: "The .NET version to setup for the build"
type: string
dotnet-target:
required: false
default: "net6.0"
default: "net8.0"
description: "The .NET target to set for JPRM"
type: string
@@ -36,4 +36,4 @@ jobs:
name: build-artifact
retention-days: 30
if-no-files-found: error
path: ${{ steps.jprm.outputs.artifact }}
path: ${{ steps.jprm.outputs.artifact }}
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
+2 -2
View File
@@ -15,7 +15,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build Dotnet
@@ -35,7 +35,7 @@ jobs:
version: "0.0.0.9000"
verbosity: debug
path: .
dotnet-target: "net6.0"
dotnet-target: "net8.0"
output: _dist
- name: Prepare GitHub Release assets
run: |-
+2 -2
View File
@@ -10,8 +10,8 @@ jobs:
build:
uses: ./.github/workflows/build.yml
with:
dotnet-version: "6.0.*"
dotnet-target: "net6.0"
dotnet-version: "8.0.*"
dotnet-target: "net8.0"
upload:
runs-on: ubuntu-latest
needs:
+18 -13
View File
@@ -10,6 +10,7 @@ using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Plugin.SSO_Auth.Config;
using Jellyfin.Plugin.SSO_Auth.Helpers;
using MediaBrowser.Common.Api;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
@@ -91,6 +92,8 @@ public class SSOController : ControllerBase
RedirectUri = GetRequestBase(config.SchemeOverride) + $"/sso/OID/{(Request.Path.Value.Contains("/start/", StringComparison.InvariantCultureIgnoreCase) ? "redirect" : "r")}/" + provider,
Scope = string.Join(" ", scopes.Prepend("openid profile")),
};
var oidEndpointUri = new Uri(config.OidEndpoint?.Trim());
options.Policy.Discovery.AdditionalEndpointBaseAddresses.Add(oidEndpointUri.GetLeftPart(UriPartial.Authority));
options.Policy.Discovery.ValidateEndpoints = !config.DoNotValidateEndpoints; // For Google and other providers with different endpoints
options.Policy.Discovery.RequireHttps = !config.DisableHttps;
options.Policy.Discovery.ValidateIssuerName = !config.DoNotValidateIssuerName;
@@ -305,7 +308,9 @@ public class SSOController : ControllerBase
RedirectUri = redirectUri,
Scope = string.Join(" ", config.OidScopes.Prepend("openid profile")),
};
options.Policy.Discovery.ValidateEndpoints = false; // For Google and other providers with different endpoints
var oidEndpointUri = new Uri(config.OidEndpoint?.Trim());
options.Policy.Discovery.AdditionalEndpointBaseAddresses.Add(oidEndpointUri.GetLeftPart(UriPartial.Authority));
options.Policy.Discovery.ValidateEndpoints = !config.DoNotValidateEndpoints; // For Google and other providers with different endpoints
var oidcClient = new OidcClient(options);
var state = await oidcClient.PrepareLoginAsync().ConfigureAwait(false);
StateManager.Add(state.State, new TimedAuthorizeState(state, DateTime.Now));
@@ -323,7 +328,7 @@ public class SSOController : ControllerBase
/// </summary>
/// <param name="provider">The name of the provider to add.</param>
/// <param name="config">The OID configuration (deserialized from a JSON post).</param>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpPost("OID/Add/{provider}")]
public void OidAdd(string provider, [FromBody] OidConfig config)
{
@@ -336,7 +341,7 @@ public class SSOController : ControllerBase
/// Deletes an OpenID provider.
/// </summary>
/// <param name="provider">Name of provider to delete.</param>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpGet("OID/Del/{provider}")]
public void OidDel(string provider)
{
@@ -349,7 +354,7 @@ public class SSOController : ControllerBase
/// Lists the OpenID providers configured. Requires administrator privileges.
/// </summary>
/// <returns>The list of OpenID configurations.</returns>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpGet("OID/Get")]
public ActionResult OidProviders()
{
@@ -380,7 +385,7 @@ public class SSOController : ControllerBase
/// This is a debug endpoint to list all running OpenID flows. Requires administrator privileges.
/// </summary>
/// <returns>The list of OpenID flows in progress.</returns>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpGet("OID/States")]
public ActionResult OidStates()
{
@@ -553,7 +558,7 @@ public class SSOController : ControllerBase
/// <param name="provider">The provider name to add.</param>
/// <param name="newConfig">The SAML configuration object (deserialized) from JSON.</param>
/// <returns>The success result.</returns>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpPost("SAML/Add/{provider}")]
public OkResult SamlAdd(string provider, [FromBody] SamlConfig newConfig)
{
@@ -568,7 +573,7 @@ public class SSOController : ControllerBase
/// </summary>
/// <param name="provider">The ID of the provider to delete.</param>
/// <returns>The success result.</returns>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpGet("SAML/Del/{provider}")]
public OkResult SamlDel(string provider)
{
@@ -582,7 +587,7 @@ public class SSOController : ControllerBase
/// Returns a list of all SAML providers configured. Requires administrator privileges.
/// </summary>
/// <returns>A list of all of the Saml providers available.</returns>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpGet("SAML/Get")]
public ActionResult SamlProviders()
{
@@ -695,7 +700,7 @@ public class SSOController : ControllerBase
/// <param name="username">The username to switch to the new provider.</param>
/// <param name="provider">The new provider to switch to.</param>
/// <returns>Whether this API endpoint succeeded.</returns>
[Authorize(Policy = "RequiresElevation")]
[Authorize(Policy = Policies.RequiresElevation)]
[HttpPost("Unregister/{username}")]
public ActionResult Unregister(string username, [FromBody] string provider)
{
@@ -787,7 +792,7 @@ public class SSOController : ControllerBase
/// <param name="jellyfinUserId">The user ID within jellyfin to link to the provider.</param>
/// <param name="authResponse">The client information to authenticate the user with.</param>
/// <returns>Whether this API endpoint succeeded.</returns>
[Authorize(Policy = "DefaultAuthorization")]
[Authorize]
[HttpPost("{mode}/Link/{provider}/{jellyfinUserId}")]
[Consumes(MediaTypeNames.Application.Json)]
[Produces(MediaTypeNames.Application.Json)]
@@ -817,7 +822,7 @@ public class SSOController : ControllerBase
/// <param name="jellyfinUserId">The user ID within jellyfin to unlink from the provider.</param>
/// <param name="canonicalName">The user ID within jellyfin to unlink.</param>
/// <returns>Whether this API endpoint succeeded.</returns>
[Authorize(Policy = "DefaultAuthorization")]
[Authorize]
[HttpDelete("{mode}/Link/{provider}/{jellyfinUserId}/{canonicalName}")]
[Consumes(MediaTypeNames.Application.Json)]
[Produces(MediaTypeNames.Application.Json)]
@@ -847,7 +852,7 @@ public class SSOController : ControllerBase
/// </summary>
/// <param name="jellyfinUserId">The user ID within jellyfin for which to return the links.</param>
/// <returns>A dictionary of provider : link mappings.</returns>
[Authorize(Policy = "DefaultAuthorization")]
[Authorize]
[HttpGet("saml/links/{jellyfinUserId}")]
[Produces(MediaTypeNames.Application.Json)]
public async Task<ActionResult<SerializableDictionary<string, IEnumerable<string>>>> GetSamlLinksByUser(Guid jellyfinUserId)
@@ -875,7 +880,7 @@ public class SSOController : ControllerBase
/// </summary>
/// <param name="jellyfinUserId">The user ID within jellyfin for which to return the links.</param>
/// <returns>A dictionary of provider : link mappings.</returns>
[Authorize(Policy = "DefaultAuthorization")]
[Authorize]
[HttpGet("oid/links/{jellyfinUserId}")]
[Produces(MediaTypeNames.Application.Json)]
public async Task<ActionResult<SerializableDictionary<string, IEnumerable<string>>>> GetOidLinksByUser(Guid jellyfinUserId)
+7 -7
View File
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.SSO_Auth</RootNamespace>
<AssemblyVersion>3.3.0.0</AssemblyVersion>
<FileVersion>3.3.0.0</FileVersion>
<AssemblyVersion>3.5.2.4</AssemblyVersion>
<FileVersion>3.5.2.4</FileVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
@@ -29,16 +29,16 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="IdentityModel.OidcClient" Version="5.0.0" />
<PackageReference Include="IdentityModel.OidcClient" Version="5.2.1" />
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
<PackageReference Include="Jellyfin.Model" Version="10.*-*" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.376" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
</ItemGroup>
@@ -83,4 +83,4 @@ public class SSOViewsController : ControllerBase
{
return ServeView(viewName);
}
}
}
+4 -1
View File
@@ -453,6 +453,9 @@ async function link(request) {
}
async function main() {
localStorage.removeItem('jellyfin_credentials');
document.getElementById('iframe-main').src = '" + baseUrl + @"/web/index.html';
var data = '" + data + @"';
while (localStorage.getItem(""_deviceId2"") == null ||
localStorage.getItem(""jellyfin_credentials"") == null ||
@@ -501,6 +504,6 @@ document.addEventListener('DOMContentLoaded', function () {
});
// https://stackoverflow.com/a/25435165
</script><iframe class='docs-texteventtarget-iframe' sandbox='allow-same-origin allow-forms allow-scripts' src='" + baseUrl + "/web/index.html' style='position: absolute;width:0;height:0;border:0;'></iframe></body></html>";
</script><iframe id='iframe-main' class='docs-texteventtarget-iframe' sandbox='allow-same-origin allow-forms allow-scripts' src='' style='position: absolute;width:0;height:0;border:0;'></iframe></body></html>";
}
}
+5 -3
View File
@@ -1,9 +1,9 @@
name: "SSO Authentication"
guid: "505ce9d1-d916-42fa-86ca-673ef241d7df"
imageUrl: "https://raw.githubusercontent.com/9p4/jellyfin-plugin-sso/main/img/logo.png"
version: "3.5.2.2"
targetAbi: "10.8.0.0"
framework: "net6.0"
version: "3.5.2.4"
targetAbi: "10.9.0.0"
framework: "net8.0"
owner: "9p4"
overview: "Authenticate users against an SSO provider."
description: |
@@ -15,6 +15,8 @@ artifacts:
- "IdentityModel.OidcClient.dll"
- "IdentityModel.dll"
changelog: |
3.5.2.4: Updates for Jellyfin 10.9
3.5.2.3: Improve OpenID discovery policy security rules, fix iOS login bugs related to cache
3.5.2.2: Fix linking page when using new paths
3.5.2.1: Hotfix for SAML null checks
3.5.2.0: Allow overriding the scheme used for generating URLs.
Generated
+3 -3
View File
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1707205916,
"narHash": "sha256-fmRJilYGlB7VCt3XsdYxrA0u8e/K84O5xYucerUY0iM=",
"lastModified": 1715499532,
"narHash": "sha256-9UJLb8rdi2VokYcfOBQHUzP3iNxOPNWcbK++ENElpk0=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "8cc79aa39bbc6eaedaf286ae655b224c71e02907",
"rev": "af8b9db5c00f1a8e4b83578acc578ff7d823b786",
"type": "github"
},
"original": {
+1 -1
View File
@@ -5,6 +5,6 @@
let pkgs = nixpkgs.legacyPackages.x86_64-linux;
in {
devShell.x86_64-linux =
pkgs.mkShell { buildInputs = [ pkgs.nodePackages.prettier pkgs.dotnet-sdk ]; };
pkgs.mkShell { buildInputs = [ pkgs.nodePackages.prettier pkgs.dotnet-sdk_8 ]; };
};
}
+68 -61
View File
@@ -1,68 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Rules for Jellyfin.Server" Description="Code analysis rules for Jellyfin.Server.csproj" ToolsVersion="14.0">
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
<Rule Id="SA1202" Action="Info" />
<!-- disable warning SA1204: Static members must appear before non-static members -->
<Rule Id="SA1204" Action="Info" />
<!-- disable warning SA1404: Code analysis suppression should have justification -->
<Rule Id="SA1404" Action="Info" />
<RuleSet Name="Rules for Jellyfin.Server"
Description="Code analysis rules for Jellyfin.Server.csproj" ToolsVersion="14.0">
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
<Rule Id="SA1202" Action="Info" />
<!-- disable warning SA1204: Static members must appear before non-static members -->
<Rule Id="SA1204" Action="Info" />
<!-- disable warning SA1404: Code analysis suppression should have justification -->
<Rule Id="SA1404" Action="Info" />
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
<Rule Id="SA1009" Action="None" />
<!-- disable warning SA1101: Prefix local calls with 'this.' -->
<Rule Id="SA1101" Action="None" />
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
<Rule Id="SA1108" Action="None" />
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
<Rule Id="SA1128" Action="None" />
<!-- disable warning SA1130: Use lambda syntax -->
<Rule Id="SA1130" Action="None" />
<!-- disable warning SA1200: 'using' directive must appear within a namespace declaration -->
<Rule Id="SA1200" Action="None" />
<!-- disable warning SA1309: Fields must not begin with an underscore -->
<Rule Id="SA1309" Action="None" />
<!-- disable warning SA1413: Use trailing comma in multi-line initializers -->
<Rule Id="SA1413" Action="None" />
<!-- disable warning SA1512: Single-line comments must not be followed by blank line -->
<Rule Id="SA1512" Action="None" />
<!-- disable warning SA1515: Single-line comment should be preceded by blank line -->
<Rule Id="SA1515" Action="None" />
<!-- disable warning SA1600: Elements should be documented -->
<Rule Id="SA1600" Action="None" />
<!-- disable warning SA1633: The file header is missing or not located at the top of the file -->
<Rule Id="SA1633" Action="None" />
</Rules>
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
<Rule Id="SA1009" Action="None" />
<!-- disable warning SA1101: Prefix local calls with 'this.' -->
<Rule Id="SA1101" Action="None" />
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
<Rule Id="SA1108" Action="None" />
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
<Rule Id="SA1128" Action="None" />
<!-- disable warning SA1130: Use lambda syntax -->
<Rule Id="SA1130" Action="None" />
<!-- disable warning SA1200: 'using' directive must appear within a namespace declaration -->
<Rule Id="SA1200" Action="None" />
<!-- disable warning SA1309: Fields must not begin with an underscore -->
<Rule Id="SA1309" Action="None" />
<!-- disable warning SA1402: File may only contain a single type -->
<Rule Id="SA1402" Action="None" />
<!-- disable warning SA1413: Use trailing comma in multi-line initializers -->
<Rule Id="SA1413" Action="None" />
<!-- disable warning SA1512: Single-line comments must not be followed by blank line -->
<Rule Id="SA1512" Action="None" />
<!-- disable warning SA1515: Single-line comment should be preceded by blank line -->
<Rule Id="SA1515" Action="None" />
<!-- disable warning SA1600: Elements should be documented -->
<Rule Id="SA1600" Action="None" />
<!-- disable warning SA1633: The file header is missing or not located at the top of the
file -->
<Rule Id="SA1633" Action="None" />
<!-- disable warning SA1649: File name should match first type name -->
<Rule Id="SA1649" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.FxCopAnalyzers" RuleNamespace="Microsoft.Design">
<!-- disable warning CA1031: Do not catch general exception types -->
<Rule Id="CA1031" Action="Info" />
<!-- disable warning CA1032: Implement standard exception constructors -->
<Rule Id="CA1032" Action="Info" />
<!-- disable warning CA1062: Validate arguments of public methods -->
<Rule Id="CA1062" Action="Info" />
<!-- disable warning CA1716: Identifiers should not match keywords -->
<Rule Id="CA1716" Action="Info" />
<!-- disable warning CA1720: Identifiers should not contain type names -->
<Rule Id="CA1720" Action="Info" />
<!-- disable warning CA1812: internal class that is apparently never instantiated.
<Rules AnalyzerId="Microsoft.CodeAnalysis.FxCopAnalyzers" RuleNamespace="Microsoft.Design">
<!-- disable warning CA1031: Do not catch general exception types -->
<Rule Id="CA1031" Action="Info" />
<!-- disable warning CA1032: Implement standard exception constructors -->
<Rule Id="CA1032" Action="Info" />
<!-- disable warning CA1062: Validate arguments of public methods -->
<Rule Id="CA1062" Action="Info" />
<!-- disable warning CA1716: Identifiers should not match keywords -->
<Rule Id="CA1716" Action="Info" />
<!-- disable warning CA1720: Identifiers should not contain type names -->
<Rule Id="CA1720" Action="Info" />
<!-- disable warning CA1812: internal class that is apparently never instantiated.
If so, remove the code from the assembly.
If this class is intended to contain only static members, make it static -->
<Rule Id="CA1812" Action="Info" />
<!-- disable warning CA1822: Member does not access instance data and can be marked as static -->
<Rule Id="CA1822" Action="Info" />
<!-- disable warning CA2000: Dispose objects before losing scope -->
<Rule Id="CA2000" Action="Info" />
<Rule Id="CA1812" Action="Info" />
<!-- disable warning CA1822: Member does not access instance data and can be marked as
static -->
<Rule Id="CA1822" Action="Info" />
<!-- disable warning CA2000: Dispose objects before losing scope -->
<Rule Id="CA2000" Action="Info" />
<!-- disable warning CA1054: Change the type of parameter url from string to System.Uri -->
<Rule Id="CA1054" Action="None" />
<!-- disable warning CA1055: URI return values should not be strings -->
<Rule Id="CA1055" Action="None" />
<!-- disable warning CA1056: URI properties should not be strings -->
<Rule Id="CA1056" Action="None" />
<!-- disable warning CA1303: Do not pass literals as localized parameters -->
<Rule Id="CA1303" Action="None" />
<!-- disable warning CA1308: Normalize strings to uppercase -->
<Rule Id="CA1308" Action="None" />
</Rules>
<!-- disable warning CA1054: Change the type of parameter url from string to System.Uri -->
<Rule Id="CA1054" Action="None" />
<!-- disable warning CA1055: URI return values should not be strings -->
<Rule Id="CA1055" Action="None" />
<!-- disable warning CA1056: URI properties should not be strings -->
<Rule Id="CA1056" Action="None" />
<!-- disable warning CA1303: Do not pass literals as localized parameters -->
<Rule Id="CA1303" Action="None" />
<!-- disable warning CA1308: Normalize strings to uppercase -->
<Rule Id="CA1308" Action="None" />
</Rules>
</RuleSet>
+20
View File
@@ -42,6 +42,25 @@ Authelia is simple to configure, and RBAC is straightforward.
Below is the `identity_providers` section of an Authelia config:
### Authelia v4.38 and above
```yaml
identity_providers:
oidc:
# hmac secret and private key given by env variables
clients:
- client_id: jellyfin
client_name: My media server
# Client secret should be randomly generated
client_secret: <redacted>
token_endpoint_auth_method: client_secret_post
authorization_policy: one_factor
redirect_uris:
- https://jellyfin.example.com/sso/OID/redirect/authelia
```
### Authelia v4.37 and below
```yaml
identity_providers:
oidc:
@@ -149,6 +168,7 @@ Ensure that the following configuration options are set:
- Access Type: Confidential
- Standard Flow Enabled
- Redirect URI: https://myjellyfin.example.com/sso/OID/redirect/PROVIDER_NAME
- Redirect URI (for Android app): org.jellyfin.mobile://login-callback
- Base URL: https://myjellyfin.example.com
Press the "Save" button at the bottom of the page and open the "Credentials" tab. Note down the secret.