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

how to use Headers for Authentication into Emby Web #3876

Open
moutasem1989 opened this issue Jan 10, 2025 · 0 comments
Open

how to use Headers for Authentication into Emby Web #3876

moutasem1989 opened this issue Jan 10, 2025 · 0 comments

Comments

@moutasem1989
Copy link

I understand that supporting OIDC/SSO is not yet planned. I would like, however, to try a work around that worked for me on several other web services that also do not support OIDC/SSO. I need help on figuring out how to log in into Emby web app with headers. Here I am using Authentik and nginx Proxy Manager to implement an SSO work around and hopefully this can be used as a guid for others who need an OIDC implimented.

Part 1 - fetching Emby AccessToken:

  • User Attributes:
    in Authentik Admin Panel, go to users and edit desired user. under "Attributes" add the following values:
emby_username: [embyaccounduser]
emby_password: [embyaccoundpassword]

Make sure to add the correct values for your account credentials.

  • API Key:
    In emby, login as Admin, and create an API key.

  • Property Mapping to fetch Emby AccessToken:
    in Authentik Admin Panel, go to CustomizationProperty Mappings > Create Scope Mapping. Fill the fieleds as follow:

Name: Emby Token

Scoop Name: ak_proxy

Under Expression add the following to fetch the code:

import json
from urllib.parse import urlencode
from urllib.request import Request, urlopen

if request.user.username == "":
  return {"ak_proxy": {"user_attributes": {"additionalHeaders": {"X-Emby-Token": "null"}}}}
else:
  embyuser = request.user.attributes.get("emby_username", "") #here we are getting the user name attribute we added earlier to the user
  embypass = request.user.attributes.get("emby_password", "") #here we are getting the password name attribute we added earlier to the user

base_url = "http://embyserver:80"  #make sure Authentik can access Emby. I use server:port because they are on the same docker network but one can also use domain
end_point = "/Users/AuthenticateByName?api_key=[here comes the API key we just created]"
json_data = {'Username': embyuser,'Pw': embypass}
postdata = json.dumps(json_data).encode()
headers = {"Content-Type": "application/json; charset=UTF-8"}
try:
  httprequest = Request(base_url + end_point, data=postdata, method="POST", headers=headers)
  with urlopen(httprequest) as response:
    responddata = json.loads(response.read().decode())
  return {"ak_proxy": {"user_attributes": {"additionalHeaders": {"X-Emby-Token": responddata['AccessToken']}}}}
except: return {"ak_proxy": {"user_attributes": {"additionalHeaders": {"X-Emby-Token": "null"}}}}

When logging in, it seems that Emby server initially response with a JSON payload containing multiple values for user, client and authentication. I am assuming that Authentication code should be suffecent.

once saved, test the scoop. if no user is selected, this should be returned: "X-Emby-Token": "null" . If a user with the correct Attributes is selected while testing, it should return the correct AccessToken. According to Emby Documentations, the value of which can be passed as X-Emby-Token header to login but I assume this does not apply to the Web App.

Part 2 - Create Proxy Authentication:

  • Authentik configurations:
    in Authentik Admin Panel, go to ApplicationsProviders and create a new Proxy Provider. Name it Emby.

Select desired Authentication flow and Authorization flow. And select Forward Auth. External host is the Domain of Emby you configured in NPM.

Under Advanced protocol settings make sure the scoop we have created is selected. once done, safe and then proceed to create an aplication for this provider. Do not forget to add the Provider just created to the Outpost.

  • NPM configurations:
    Edit the Emby Host in NPM. Under Advanced add this to Custom Nginx Configuration: (This is where i am currently stuck and need help)
proxy_buffers 8 16k;
proxy_buffer_size 32k;
port_in_redirect off;
location /authentik {
    proxy_pass          $forward_scheme://$server:$port/web;
    proxy_set_header Upgrade $http_upgrade;
    auth_request     /outpost.goauthentik.io/auth/nginx;
    error_page       401 = @goauthentik_proxy_signin;
    auth_request_set $auth_cookie $upstream_http_set_cookie;
    add_header       Set-Cookie $auth_cookie;
    auth_request_set $authentik_auth $upstream_http_x_emby_token;
    proxy_set_header X-Emby-Token ${authentik_auth};
    proxy_pass_header X-Emby-Token;
}
location /outpost.goauthentik.io {
    proxy_pass              https://authentik-server:9443/outpost.goauthentik.io;
    proxy_set_header        Host $host;
    proxy_set_header        X-Original-URL $scheme://$http_host$request_uri;
    add_header              Set-Cookie $auth_cookie;
    auth_request_set        $auth_cookie $upstream_http_set_cookie;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
}
location @goauthentik_proxy_signin {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 /outpost.goauthentik.io/start?rd=$request_uri;
}

Theoratically, Normal login should be at https://emby.domain.tld so it does not breake Emby Clients. but when going to _https://emby.domain/authentik_ it should redirect to authenticate with Authentik. In the process it would fetch a X-Emby-Token. tis would be passed as header to login as the user assosiated with Authentik. Sadly it does not work yet.

I noticed that the response to the login request has a JSON payload. does that mean that login can only compleate when the payload is provided? which i assume would not work since it was created for the python request not the browser the user is loging in from.

Is there a way to login into Emby Web wsing headers passed in NPM?
any help is greatly appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant