# Request
Basically, I'd like to be able to open a link with a custom schema …to the app that supplies:
```yaml
- serverUrl
- userId
- accessToken
```
To an intent handler (or whatever we call it in ios), that stores that information in the web client to initiate a session, and skips the login.
This would intend to accomodate single-sign-on via plugin, eg the popular
https://github.com/9p4/jellyfin-plugin-sso
Here is a demonstration of the current flow on the android client (behaves similarly)
https://user-images.githubusercontent.com/39424834/180710755-63c8addc-7c18-412f-8e1d-47bc411a1006.mp4
Take note that although we can get a via single sign on, the new session is in the browser, rather than the jellyfin app.
From a technical perspective, this is not too hard to implement, both Android and iOS have APIs for using custom links open apps with some kind of data payload https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app
# Background
I am one of the maintainers of a plugin that provides single-sign-on to jellyfin servers
https://github.com/9p4/jellyfin-plugin-sso
The plugin is now at a stage of development where its functionality is quite mature, but its main limitation is that it only supports the web-client.
## Flows
Assume the jellyfin server lives at `https://myjellyfin.com`
The plugin can serve a page that initiates the SSO flow (either oauth or saml, I'm mainly going to talk about oauth), this page is at `https://myjellyfin.com/SSO/OID/p/<provider_name>`.
The plugin also serves a callback page for completing SSO flows, eg `https://myjellyfin.com/SSO/OID/r/<provider_name>`.
For example, you might use Google as your provider, so you'd use `https://myjellyfin.com/SSO/OID/p/google`, and `https://myjellyfin.com/SSO/OID/r/google`
On the web-client, the SSO flow from login-page to signed in dashboard is straightforward.
### User perspective (Web client):
1. On the login page, not signed in
1. Click on the link to "Sign in via SSO"
* Get redirected to the sign in-page for your SSO provider (eg, google)
* complete the flow on your SSO provider (eg, confirm sign-in, or select your account)
* get redirected back to jellyfin, and you're signed in
### Actual flow (Web client)
1. User on the login page, not signed in
2. User click on the link to "Sign in via SSO"
3. **(OAuth magic)** This takes user to a page (`https://myjellyfin.com/SSO/OID/p/google` with a javascript client that initiates an OAuth flow
1. The js client redirects the user to `https://accounts.google.com/o/oauth2/v2/auth`
* The user completes the prompt on google
2. Google redirects to `https://myjellyfin.com/SSO/OID/r/google` with the oauth state required
4. On the redirect page, a js client uses the state given by google to confirm a valid session with the jellyfin server
* The server gives the client a user ID + authorization token
* THe client stores this in localStorage, with enough information for the browser to now have a valid, logged in session
* The client redirects back to the homepage, (`https://myjellyfin.com`) and is now logged in
This flow works reliably. An important note, however, is that a lot of the oauth client-handling is done using javascript clients in web pages server directly by the plugin.
### Limitations
Because the above flow relies on a browser oauth client, it effectively establishes a valid session **within the browser**
https://github.com/9p4/jellyfin-plugin-sso/blob/fad5a62e07e44c84bc94d5962b8b79e80c102ee8/SSO-Auth/WebResponse.cs#L449-L458
```javascript
var responseJson = JSON.parse(response);
var userId = 'user-' + responseJson['User']['Id'] + '-' + responseJson['User']['ServerId'];
responseJson['User']['EnableAutoLogin'] = true;
localStorage.setItem(userId, JSON.stringify(responseJson['User']));
var jfCreds = JSON.parse(localStorage.getItem('jellyfin_credentials'));
jfCreds['Servers'][0]['AccessToken'] = responseJson['AccessToken'];
jfCreds['Servers'][0]['UserId'] = responseJson['User']['Id'];
localStorage.setItem('jellyfin_credentials', JSON.stringify(jfCreds));
localStorage.setItem('enableAutoLogin', 'true');
window.location.replace('" + baseUrl + @"');
```
It literally stores all the state the web-app needs in order to resume a session.
The problem is, that we can't use this to log-into the android or ios app
**Additional context**
<details>
<summary>
Discussion migrated from Matrix - Pretty long but included for posterity
</summary>
[Matthew Strasiotto](https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$qultQ8GE3lk6Jmf0N1MIkSj6OmZ9BqqNzpNG4xP9--A?via=bonifacelabs.ca&via=t2bot.io&via=matrix.org): (July 6ish)
> question -
> Is it at all possible to add an intent to the jf android app that signs onto a user account using a token generated from elsewhere?
> i'm reading about SSO for android, and how to add SSO clients to android apps
> https://github.com/openid/AppAuth-Android
>
> i'm a contributor to https://github.com/9p4/jellyfin-plugin-sso
> the actual oauth client works on jellyfin-web, & i'd like to get it to work for the android client -
> The best way to do that is probably something along the lines of AppAuth-Android / maybe intent filters
>
>
> in reality, as long as we can trigger some kind of redirect back to the jellyfin app with enough data from the authenticated web-session to get a user logged into the app, there isn't a tonne of work
>
...
[Matthew Strasiottio](https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$8C4eqpMWwCWa0Gy98pbg0wzlkaKdc_87syR_FUIOL-s?via=bonifacelabs.ca&via=t2bot.io&via=matrix.org):
> [mcarlton](https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$n_R7GOhYoukWRovxbBn7v2Uou4-E42oek3h5o9WLrGM?via=bonifacelabs.ca&via=t2bot.io&via=matrix.org)
> Matthew Strasiotto
>
> > would quick connect accomplish what you're looking for? i'm not sure if it can be used in the android app as a client side yet
>
> Quick connect is good, and a good workaround for the use-case where people's primary authentication is SSO
> It does work on the android app, but the limitation is that the current SSO flow my plugin gives will basically Auth a session in the browser, and a user would need to
> 1. Initiate browser SSO
> 2. Swap back to jellyfin, initiate quick connect
> 3. Swap back to browser, complete quick connect flow
>
> Pretty clunky, good for Auth across devices tho
[Matthew Strasiotto](https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$Yr7YShEbHvvZCsHIgz4hZbtAELNGxugmjdp6V1qFoBQ?via=bonifacelabs.ca&via=t2bot.io&via=matrix.org) July 17:
> I'd like to support the SSO plugin i contribute to in jellyfin-android & jellyfin-expo
> I've heard from maintainers that they're not interested in supporting SSO in their apps at this stage as it would require each client implement it.
> I'd like to get around that with fully browser/web-app based implementation that's handled by the plugin, which basically handles the flow, gets the userID + access token
>
> The browser client would then open a custom scheme link that passes the server ID, user ID & access token back to the app, and triggers a "sign on" intent
>
> for either case, the jellyfin-android + jellyfin-expo app would only have to handle an intent being given with fully-formed credentials, and everything else could defer back to their web wrappers.
>
> Before i commence work on this, I'm curious if maintainers are open to considering PRs on either project (jf-android / jf-expo) that allow custom URL scheme handling for the scope of "given serverID, userID & accessToken, initate a session then commence main activity" so that my plugin can handle the rest from a native browser
![image](https://user-images.githubusercontent.com/39424834/180710127-d02fb28b-f6a7-4edb-9a5f-1512c961b933.png)
![image](https://user-images.githubusercontent.com/39424834/180710179-eb04ab85-f442-4c79-9fce-25bc5556f27a.png)
![image](https://user-images.githubusercontent.com/39424834/180710206-baa22bc8-04b8-4cf7-b693-4d348478dc89.png)
July 21
https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$qn4tvt0GXVlDnBYIGgM0wCuO0C2SO2AAUyAI9xiQHlc?via=bonifacelabs.ca&via=t2bot.io&via=matrix.org
![image](https://user-images.githubusercontent.com/39424834/180710303-47979e81-4cfa-4b09-9926-4adfbac28e6d.png)
![image](https://user-images.githubusercontent.com/39424834/180710385-33b0f080-0b48-4b3a-9e78-e1c992b8d0a7.png)
![image](https://user-images.githubusercontent.com/39424834/180710445-f995c547-0122-4e71-a8e3-fe6d7a7ab562.png)
</details>