forked from mirrors/jellyfin-plugin-sso
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 94d1c7a95a | |||
| a1a355591c | |||
| 71802d954c | |||
| f37e8dd3bb | |||
| 9b667b3175 | |||
| 2c3fc4d8e1 | |||
| f897704100 | |||
| d0b9b10a36 | |||
| 172f22e19f | |||
| 5777c8038e | |||
| 95776b427b | |||
| b82a3867e4 | |||
| 657f90ef13 | |||
| dd01e729b8 | |||
| f2452103bf | |||
| 076cb1b893 | |||
| defab9c4e8 | |||
| 2ead846ed8 |
@@ -1,13 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: a055
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
@@ -1,11 +0,0 @@
|
||||
name: Lint Commit Messages
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
commitlint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: wagoid/commitlint-github-action@4caf21aed4a778f940d0b17eb109942ef167bb27
|
||||
@@ -91,6 +91,35 @@ The nightly build may have new features unavailable in other builds, but **be wa
|
||||
|
||||
## Examples
|
||||
|
||||
### Creating A Login Button On The Main Page
|
||||
|
||||
In the Jellyfin administration UI, under "General", there is a "Branding" section. In that section, add the following code in the "Login disclaimer" block (replacing `PROVIDER_NAME` and the domain):
|
||||
|
||||
```html
|
||||
<a
|
||||
href="https://jellyfin.example.com/sso/OID/start/PROVIDER_NAME"
|
||||
class="raised cancel block emby-button"
|
||||
>Sign in with SSO</a
|
||||
>
|
||||
```
|
||||
|
||||
Then, add the following code in the "Custom CSS code" section:
|
||||
|
||||
```css
|
||||
a.raised.emby-button {
|
||||
padding: 0.9em 1em;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.disclaimerContainer {
|
||||
display: block;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
For more information, refer to [issue #16](https://github.com/9p4/jellyfin-plugin-sso/issues/16).
|
||||
|
||||
### SAML
|
||||
|
||||
Example for adding a SAML configuration with the API using [curl](https://curl.se/):
|
||||
@@ -104,9 +133,9 @@ The SAML provider must have the following configuration (I am using Keycloak, an
|
||||
- Sign Documents on
|
||||
- Sign Assertions off
|
||||
- Client Signature Required off
|
||||
- Redirect URI: [https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME](https://myjellyfin.example.com/sso/OID/p/PROVIDER_NAME)
|
||||
- Redirect URI: [https://myjellyfin.example.com/sso/SAML/post/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME)
|
||||
- Base URL: [https://myjellyfin.example.com](https://myjellyfin.example.com)
|
||||
- Master SAML processing URL: [https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME)
|
||||
- Master SAML processing URL: [https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME)
|
||||
|
||||
Make sure that `clientid` is replaced with the actual client ID and `PROVIDER_NAME` is replaced with the chosen provider name!
|
||||
|
||||
@@ -120,7 +149,7 @@ The OpenID provider must have the following configuration (again, I am using Key
|
||||
|
||||
- Access Type: Confidential
|
||||
- Standard Flow Enabled
|
||||
- Redirect URI: [https://myjellyfin.example.com/sso/OID/r/PROVIDER_NAME](https://myjellyfin.example.com/sso/OID/r/PROVIDER_NAME)
|
||||
- Redirect URI: [https://myjellyfin.example.com/sso/OID/redirect/PROVIDER_NAME](https://myjellyfin.example.com/sso/OID/redirect/PROVIDER_NAME)
|
||||
- Base URL: [https://myjellyfin.example.com](https://myjellyfin.example.com)
|
||||
|
||||
Make sure that `clientid` is replaced with the actual client ID and `PROVIDER_NAME` is replaced with the chosen provider name!
|
||||
@@ -133,8 +162,8 @@ The API is all done from a base URL of `/sso/`
|
||||
|
||||
#### Flow
|
||||
|
||||
- POST `SAML/p/PROVIDER_NAME`: This is the SAML POST endpoint. It accepts a form response from the SAML provider and returns HTML and JavaScript for the client to login with a given provider name.
|
||||
- GET `SAML/p/PROVIDER_NAME`: This is the SAML initiator: it will begin the authorization flow for SAML with a given provider name.
|
||||
- POST `SAML/start/PROVIDER_NAME`: This is the SAML POST endpoint. It accepts a form response from the SAML provider and returns HTML and JavaScript for the client to login with a given provider name.
|
||||
- GET `SAML/start/PROVIDER_NAME`: This is the SAML initiator: it will begin the authorization flow for SAML with a given provider name.
|
||||
- POST `SAML/Auth/PROVIDER_NAME`: This is the SAML client-side API: the HTML and JavaScript client will call this endpoint to receive Jellyfin credentials given a provider name. Post format is in JSON with the following keys:
|
||||
- `deviceId`: string. Device ID.
|
||||
- `deviceName`: string. Device name.
|
||||
@@ -164,6 +193,7 @@ These all require authorization. Append an API key to the end of the request: `c
|
||||
- `enableLiveTv`: boolean. Whether to allow Live TV by default. This applies even if `enableLiveTvRoles` is enabled.
|
||||
- `enableLiveTvManagement`: boolean. Whether to allow Live TV management by default. This applies even if `enableLiveTvRoles` is enabled.
|
||||
- `defaultProvider`: string. The set provider then gets assigned to the user after they have logged in. If it is not set, nothing is changed. With this, a user can login with SSO but is still able to log in via other providers later. See the `Unregister` endpoint.
|
||||
- `schemeOverride`: string. Sets the scheme for URLs used. Can be useful if the plugin refuses to use HTTPS URLs.
|
||||
- GET `SAML/Del/PROVIDER_NAME`: This removes a configuration for SAML for a given provider name.
|
||||
- GET `SAML/Get`: Lists the configurations currently available.
|
||||
|
||||
@@ -171,8 +201,8 @@ These all require authorization. Append an API key to the end of the request: `c
|
||||
|
||||
#### Flow
|
||||
|
||||
- GET `OID/r/PROVIDER_NAME`: This is the OpenID callback path. This will return HTML and JavaScript for the client to login with a given provider name.
|
||||
- GET `OID/p/PROVIDER_NAME`: This is the OpenID initiator: it will begin the authorization flow for OpenID with a given provider name.
|
||||
- GET `OID/redirect/PROVIDER_NAME`: This is the OpenID callback path. This will return HTML and JavaScript for the client to login with a given provider name.
|
||||
- GET `OID/start/PROVIDER_NAME`: This is the OpenID initiator: it will begin the authorization flow for OpenID with a given provider name.
|
||||
- POST `OID/Auth/PROVIDER_NAME`: This is the OpenID client-side API: the HTML and JavaScript client will call this endpoint to receive Jellyfin credentials for a given provider name. Post format is in JSON with the following keys:
|
||||
- `deviceId`: string. Device ID.
|
||||
- `deviceName`: string. Device name.
|
||||
@@ -207,7 +237,10 @@ These all require authorization. Append an API key to the end of the request: `c
|
||||
- Leave empty to only request the default scopes.
|
||||
- `defaultProvider`: string. The set provider then gets assigned to the user after they have logged in. If it is not set, nothing is changed. With this, a user can login with SSO but is still able to log in via other providers later. See the `Unregister` endpoint.
|
||||
- `defaultUsernameClaim`: string. The provider will use the claim to create the users' usernames. If not set, it fallbacks to `preferred_username`.
|
||||
- `requireHttps`: boolean. Determines whether the OpenID discovery endpoint requires HTTP. It is advised NOT to set this to false. If not set, it fallbacks to `true`.
|
||||
- `disableHttps`: boolean. Determines whether the OpenID discovery endpoint requires HTTPS.
|
||||
- `doNotValidateEndpoints`: boolean. Determines whether the OpenID discovery process will validate endpoints. This may be required for Google.
|
||||
- `doNotValidateIssuerName`: boolean. Determines whether the OpenID discovery process will validate the OpenID issuer name.
|
||||
- `schemeOverride`: string. Sets the scheme for URLs used. Can be useful if the plugin refuses to use HTTPS URLs.
|
||||
- GET `OID/Del/PROVIDER_NAME`: This removes a configuration for OpenID for a given provider name.
|
||||
- GET `OID/Get`: Lists the configurations currently available.
|
||||
- GET `OID/States`: Lists currently active OpenID flows in progress.
|
||||
@@ -218,18 +251,24 @@ These all require authorization. Append an API key to the end of the request: `c
|
||||
|
||||
## Limitations
|
||||
|
||||
There is no GUI to sign in. You have to make it yourself! The buttons should redirect to something like this: [https://myjellyfin.example.com/sso/SAML/p/clientid](https://myjellyfin.example.com/sso/SAML/p/clientid) replacing `clientid` with the provider client ID and `SAML` with the auth scheme (either `SAML` or `OID`).
|
||||
Logging in with an SSO account that has the same username as an existing Jellyfin account will override the permissions for the user. Use caution when overriding the administrator account!
|
||||
|
||||
~~There is no GUI to sign in. You have to make it yourself! The buttons should redirect to something like this: [https://myjellyfin.example.com/sso/SAML/start/clientid](https://myjellyfin.example.com/sso/SAML/start/clientid) replacing `clientid` with the provider client ID and `SAML` with the auth scheme (either `SAML` or `OID`).~~
|
||||
|
||||
~~Furthermore, there is no functional admin page (yet). PRs for this are welcome. In the meantime, you have to interact with the API to add or remove configurations.~~ Added by [strazto](https://github.com/strazto) in PR [#18](https://github.com/9p4/jellyfin-plugin-sso/pull/18) and [#27](https://github.com/9p4/jellyfin-plugin-sso/pull/27).
|
||||
|
||||
There is also no logout callback. Logging out of Jellyfin will log you out of Jellyfin only, instead of the SSO provider as well.
|
||||
|
||||
~~This only supports Jellyfin on it's own domain (for now). This is because I'm using string concatenation for generating some URLs. A PR is welcome to patch this.~~ Fixed in [PR #1](https://github.com/9p4/jellyfin-plugin-sso/pull/1).
|
||||
~~This only supports Jellyfin on its own domain (for now). This is because I'm using string concatenation for generating some URLs. A PR is welcome to patch this.~~ Fixed in [PR #1](https://github.com/9p4/jellyfin-plugin-sso/pull/1).
|
||||
|
||||
**This only works on the web UI**. ~~The user must open the Jellyfin web UI BEFORE using the SSO program to populate some values in the localStorage.~~ Fixed by implementing a comment by [Pfuenzle](https://github.com/Pfuenzle) in [Issue #5](https://github.com/9p4/jellyfin-plugin-sso/issues/5#issuecomment-1041864820).
|
||||
|
||||
# Contributing
|
||||
|
||||
## Dependencies
|
||||
|
||||
This project uses Nix flakes to manage development dependencies. Run `nix develop` to use the same toolchain versions.
|
||||
|
||||
## Building
|
||||
|
||||
This is built with .NET 6.0. Build with `dotnet publish .` for the debug release in the `SSO-Auth` directory. Copy over the `IdentityModel.OidcClient.dll`, the `IdentityModel.dll` and the `SSO-Auth.dll` files in the `/bin/Debug/net6.0/publish` directory to a new folder in your Jellyfin configuration: `config/plugins/sso`.
|
||||
|
||||
@@ -65,6 +65,7 @@ public class SSOController : ControllerBase
|
||||
/// <returns>A webpage that will complete the client-side flow.</returns>
|
||||
// Actually a GET: https://github.com/IdentityModel/IdentityModel.OidcClient/issues/325
|
||||
[HttpGet("OID/r/{provider}")]
|
||||
[HttpGet("OID/redirect/{provider}")]
|
||||
public async Task<ActionResult> OidPost(
|
||||
[FromRoute] string provider,
|
||||
[FromQuery] string state) // Although this is a GET function, this function is called `Post` for consistency with SAML
|
||||
@@ -86,11 +87,12 @@ public class SSOController : ControllerBase
|
||||
Authority = config.OidEndpoint?.Trim(),
|
||||
ClientId = config.OidClientId?.Trim(),
|
||||
ClientSecret = config.OidSecret?.Trim(),
|
||||
RedirectUri = GetRequestBase() + "/sso/OID/r/" + provider,
|
||||
RedirectUri = GetRequestBase(config.SchemeOverride) + $"/sso/OID/{(Request.Path.Value.Contains("/start/", StringComparison.InvariantCultureIgnoreCase) ? "redirect" : "r")}/" + provider,
|
||||
Scope = string.Join(" ", config.OidScopes.Prepend("openid profile")),
|
||||
};
|
||||
options.Policy.Discovery.ValidateEndpoints = false; // For Google and other providers with different endpoints
|
||||
options.Policy.Discovery.RequireHttps = config.RequireHttps;
|
||||
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;
|
||||
var oidcClient = new OidcClient(options);
|
||||
var currentState = StateManager[state].State;
|
||||
var result = await oidcClient.ProcessResponseAsync(Request.QueryString.Value, currentState).ConfigureAwait(false);
|
||||
@@ -244,7 +246,7 @@ public class SSOController : ControllerBase
|
||||
if (StateManager[state].Valid)
|
||||
{
|
||||
_logger.LogInformation($"Is request linking: {isLinking}");
|
||||
return Content(WebResponse.Generator(data: state, provider: provider, baseUrl: GetRequestBase(), mode: "OID", isLinking: isLinking), MediaTypeNames.Text.Html);
|
||||
return Content(WebResponse.Generator(data: state, provider: provider, baseUrl: GetRequestBase(config.SchemeOverride), mode: "OID", isLinking: isLinking), MediaTypeNames.Text.Html);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -269,6 +271,7 @@ public class SSOController : ControllerBase
|
||||
/// <param name="isLinking">Whether or not this request is to link accounts (Rather than authenticate).</param>
|
||||
/// <returns>An asynchronous result for the authentication.</returns>
|
||||
[HttpGet("OID/p/{provider}")]
|
||||
[HttpGet("OID/start/{provider}")]
|
||||
public async Task<ActionResult> OidChallenge(string provider, [FromQuery] bool isLinking = false)
|
||||
{
|
||||
Invalidate();
|
||||
@@ -289,7 +292,7 @@ public class SSOController : ControllerBase
|
||||
Authority = config.OidEndpoint?.Trim(),
|
||||
ClientId = config.OidClientId?.Trim(),
|
||||
ClientSecret = config.OidSecret?.Trim(),
|
||||
RedirectUri = GetRequestBase() + "/sso/OID/r/" + provider,
|
||||
RedirectUri = GetRequestBase(config.SchemeOverride) + $"/sso/OID/{(Request.Path.Value.Contains("/start/", StringComparison.InvariantCultureIgnoreCase) ? "redirect" : "r")}/" + provider,
|
||||
Scope = string.Join(" ", config.OidScopes.Prepend("openid profile")),
|
||||
};
|
||||
options.Policy.Discovery.ValidateEndpoints = false; // For Google and other providers with different endpoints
|
||||
@@ -423,6 +426,7 @@ public class SSOController : ControllerBase
|
||||
/// </param>
|
||||
/// <returns>A webpage that will complete the client-side flow.</returns>
|
||||
[HttpPost("SAML/p/{provider}")]
|
||||
[HttpPost("SAML/post/{provider}")]
|
||||
public ActionResult SamlPost(string provider, [FromQuery] string relayState = null)
|
||||
{
|
||||
SamlConfig config;
|
||||
@@ -470,7 +474,7 @@ public class SSOController : ControllerBase
|
||||
WebResponse.Generator(
|
||||
data: Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(samlResponse.Xml)),
|
||||
provider: provider,
|
||||
baseUrl: GetRequestBase(),
|
||||
baseUrl: GetRequestBase(config.SchemeOverride),
|
||||
mode: "SAML",
|
||||
isLinking: isLinking),
|
||||
MediaTypeNames.Text.Html);
|
||||
@@ -494,6 +498,7 @@ public class SSOController : ControllerBase
|
||||
/// <param name="isLinking">Whether this flow intends to link an account, or initiate auth.</param>
|
||||
/// <returns>A redirect to the SAML provider's auth page.</returns>
|
||||
[HttpGet("SAML/p/{provider}")]
|
||||
[HttpGet("SAML/start/{provider}")]
|
||||
public RedirectResult SamlChallenge(string provider, [FromQuery] bool isLinking = false)
|
||||
{
|
||||
SamlConfig config;
|
||||
@@ -516,7 +521,7 @@ public class SSOController : ControllerBase
|
||||
|
||||
var request = new AuthRequest(
|
||||
config.SamlClientId.Trim(),
|
||||
GetRequestBase() + "/sso/SAML/p/" + provider);
|
||||
GetRequestBase(config.SchemeOverride) + $"/sso/SAML/{(Request.Path.Value.Contains("/start/", StringComparison.InvariantCultureIgnoreCase) ? "post" : "p")}/" + provider);
|
||||
|
||||
return Redirect(request.GetRedirectUrl(config.SamlEndpoint.Trim(), relayState));
|
||||
}
|
||||
@@ -1037,7 +1042,7 @@ public class SSOController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
private string GetRequestBase()
|
||||
private string GetRequestBase(string schemeOverride = null)
|
||||
{
|
||||
int requestPort = Request.Host.Port ?? -1;
|
||||
if ((requestPort == 80 && string.Equals(Request.Scheme, "http", StringComparison.OrdinalIgnoreCase)) || (requestPort == 443 && string.Equals(Request.Scheme, "https", StringComparison.OrdinalIgnoreCase)))
|
||||
@@ -1045,9 +1050,14 @@ public class SSOController : ControllerBase
|
||||
requestPort = -1;
|
||||
}
|
||||
|
||||
if (schemeOverride != "http" && schemeOverride != "https")
|
||||
{
|
||||
schemeOverride = null;
|
||||
}
|
||||
|
||||
return new UriBuilder
|
||||
{
|
||||
Scheme = Request.Scheme,
|
||||
Scheme = schemeOverride ?? Request.Scheme,
|
||||
Host = Request.Host.Host,
|
||||
Port = requestPort,
|
||||
Path = Request.PathBase
|
||||
|
||||
@@ -126,6 +126,11 @@ public class SamlConfig
|
||||
/// </summary>
|
||||
public string DefaultProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the redirect scheme override.
|
||||
/// </summary>
|
||||
public string SchemeOverride { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a mapping of canonical names from the provider to jellyfin user ids.
|
||||
/// </summary>
|
||||
@@ -250,6 +255,11 @@ public class OidConfig
|
||||
/// </summary>
|
||||
public string DefaultProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the redirect scheme override.
|
||||
/// </summary>
|
||||
public string SchemeOverride { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a mapping of canonical names from the provider to jellyfin user ids.
|
||||
/// </summary>
|
||||
@@ -276,7 +286,17 @@ public class OidConfig
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether HTTPS in the discovery endpoint is required.
|
||||
/// </summary>
|
||||
public bool RequireHttps { get; set; }
|
||||
public bool DisableHttps { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the OpenID endpoints are validated.
|
||||
/// </summary>
|
||||
public bool DoNotValidateEndpoints { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the OpenID issuer name is validated.
|
||||
/// </summary>
|
||||
public bool DoNotValidateIssuerName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -447,7 +447,7 @@
|
||||
<input
|
||||
is="emby-checkbox"
|
||||
id="EnableLiveTvManagement"
|
||||
name="EnableLiveTv"
|
||||
name="EnableLiveTvManagement"
|
||||
type="checkbox"
|
||||
class="sso-toggle"
|
||||
/>
|
||||
@@ -559,6 +559,66 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer">
|
||||
<label>
|
||||
<input
|
||||
is="emby-checkbox"
|
||||
id="DisableHttps"
|
||||
name="DisableHttps"
|
||||
type="checkbox"
|
||||
class="sso-toggle"
|
||||
/>
|
||||
<span>Disable OpenID HTTPS Discovery (Insecure)</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="checkboxContainer checkboxContainer-withDescription"
|
||||
>
|
||||
<label>
|
||||
<input
|
||||
is="emby-checkbox"
|
||||
id="DoNotValidateEndpoints"
|
||||
name="DoNotValidateEndpoints"
|
||||
type="checkbox"
|
||||
class="sso-toggle"
|
||||
/>
|
||||
<span>Do Not Validate OpenID Endpoints (Insecure)</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">
|
||||
May be required for Google OpenID
|
||||
</div>
|
||||
</div>
|
||||
<div class="checkboxContainer">
|
||||
<label>
|
||||
<input
|
||||
is="emby-checkbox"
|
||||
id="DoNotValidateIssuerName"
|
||||
name="DoNotValidateIssuerName"
|
||||
type="checkbox"
|
||||
class="sso-toggle"
|
||||
/>
|
||||
<span>Do Not Validate OpenID Issuer Name (Insecure)</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="RoleClaim"
|
||||
>Scheme Override</label
|
||||
>
|
||||
<input
|
||||
is="emby-input"
|
||||
id="SchemeOverride"
|
||||
type="text"
|
||||
class="sso-text"
|
||||
/>
|
||||
<div class="fieldDescription">
|
||||
If the plugin is redirecting to an insecure URL, set this to
|
||||
"https"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
id="SaveProvider"
|
||||
is="emby-button"
|
||||
|
||||
@@ -493,7 +493,7 @@ async function main() {
|
||||
jfCreds['Servers'][0]['UserId'] = responseJson['User']['Id'];
|
||||
localStorage.setItem('jellyfin_credentials', JSON.stringify(jfCreds));
|
||||
localStorage.setItem('enableAutoLogin', 'true');
|
||||
window.location.replace('" + baseUrl + @"');
|
||||
window.location.replace('" + baseUrl + @"/web/index.html');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
@@ -501,6 +501,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 + "' style='position: absolute;width:0;height:0;border:0;'></iframe></body></html>";
|
||||
</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>";
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -1,7 +1,7 @@
|
||||
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.0.0"
|
||||
version: "3.5.2.0"
|
||||
targetAbi: "10.8.0.0"
|
||||
framework: "net6.0"
|
||||
owner: "9p4"
|
||||
@@ -15,6 +15,9 @@ artifacts:
|
||||
- "IdentityModel.OidcClient.dll"
|
||||
- "IdentityModel.dll"
|
||||
changelog: |
|
||||
3.5.2.0: Allow overriding the scheme used for generating URLs.
|
||||
3.5.1.1: Change iframe URL to point to the web UI instead of the root
|
||||
3.5.1.0: Improved paths! No more obscure "p" versus "r" URLs! Improve final redirect for automatic authentication. Add more configuration options for OpenID discovery.
|
||||
3.5.0.0: Add support for Live TV authentication. Fix various null pointer bugs.
|
||||
3.4.0.0: Add user self-service for linking existing accounts + managing existing links. Allow IDP accounts to be linked to jellyfin accounts with a different display-name.
|
||||
3.3.0.0: Add fallback authentication provider. Add OpenID admin page.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
+6
-5
@@ -17,6 +17,7 @@ This section is broken into providers that support Role-Based Access Control (RB
|
||||
|
||||
- ✅ Google OIDC
|
||||
- ❗ Usernames are numeric
|
||||
- ❗ Requires disabling validating OpenID endpoints
|
||||
|
||||
## General Options, when RBAC is supported
|
||||
|
||||
@@ -52,7 +53,7 @@ identity_providers:
|
||||
secret: <redacted>
|
||||
authorization_policy: one_factor
|
||||
redirect_uris:
|
||||
- https://jellyfin.example.com/sso/OID/r/authelia
|
||||
- https://jellyfin.example.com/sso/OID/redirect/authelia
|
||||
```
|
||||
|
||||
### Jellyfin's Config
|
||||
@@ -113,7 +114,7 @@ Now we can add this property mapping to authentik's Jellyfin OAuth provider:
|
||||

|
||||
|
||||
- Edit / Update your Jellyfin OAuth provider
|
||||
- Verify your **"Redirect URIs/Origins (RegEx)"** follows the format: `https://domain.tld/sso/OID/r/Authentik`.
|
||||
- Verify your **"Redirect URIs/Origins (RegEx)"** follows the format: `https://domain.tld/sso/OID/redirect/Authentik`.
|
||||
- Under **"Advanced Protocol Settings"**, add the **Group Membership** Scope
|
||||
|
||||

|
||||
@@ -145,7 +146,7 @@ Ensure that the following configuration options are set:
|
||||
|
||||
- Access Type: Confidential
|
||||
- Standard Flow Enabled
|
||||
- Redirect URI: https://myjellyfin.example.com/sso/OID/r/PROVIDER_NAME
|
||||
- Redirect URI: https://myjellyfin.example.com/sso/OID/redirect/PROVIDER_NAME
|
||||
- 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.
|
||||
@@ -179,9 +180,9 @@ Ensure that the following configuration options are set:
|
||||
- Sign Documents on
|
||||
- Sign Assertions off
|
||||
- Client Signature Required off
|
||||
- Redirect URI: [https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME)
|
||||
- Redirect URI: [https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME)
|
||||
- Base URL: [https://myjellyfin.example.com](https://myjellyfin.example.com)
|
||||
- Master SAML processing URL: [https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/p/PROVIDER_NAME)
|
||||
- Master SAML processing URL: [https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME](https://myjellyfin.example.com/sso/SAML/start/PROVIDER_NAME)
|
||||
|
||||
Press the "Save" button at the bottom of the page.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user