home-assistant integrated sso

Other software can directly use nginx as a proxy to add authentication, but this hass is really strong in user security and privacy. To be a proxy, you need to configure a whitelist, and the supported three-party authentication is not suitable for my needs. I have to change the source code. OK, later I found a compromise without changing the source code

reference article

Deploy hass in containerd and integrate sso

I deployed it to kubernetes, refer to the link

Login hass locally and create a long-lived token

insert image description here

hass configuration file

# 配置nginx代理
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 10.234.104.88 #这个地址是nginx服务的ip地址

nginx configuration file

server {
    
    
    listen       86;
    listen  [::]:86;
    server_name  localhost;
	#替换响应中的内容,类似于string.replace函数
    sub_filter '<head>' '<head><script>window.externalApp={getExternalAuth:function(){window.externalAuthSetToken(true,{"access_token":"第一步创建长期的令牌","expires_in":248832000});},revokeExternalAuth:function(){window.externalAuthRevokeToken(false);}};</script>';
    sub_filter_once on;

    location / {
    
    
        proxy_pass http://localhost:8123;#hass地址
        auth_request http://xxx/sso/auth;#sso鉴权接口地址
        proxy_set_header Host $host;
        proxy_set_header Accept-Encoding "";
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header X-Real-IP $remote_addr; # //一层代理时是用户真实ip,二层代理时是第一台nginxip
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # //一层代理时没有值,多层代理里面会存储多个ip值,第一个值就是真实用户ip
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /api/websocket {
    
    
        proxy_pass http://localhost:8123/api/websocket;
        auth_request http://xxx/sso/auth;#sso鉴权接口地址
        proxy_set_header Host $host;
        proxy_set_header Accept-Encoding "";
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header X-Real-IP $remote_addr; # //一层代理时是用户真实ip,二层代理时是第一台nginxip
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # //一层代理时没有值,多层代理里面会存储多个ip值,第一个值就是真实用户ip
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /auth/authorize {
    
    
        # tell nginx that this request requires authentication with oauth2_proxy
        auth_request http://xxx/sso/auth;#sso鉴权接口地址
        # redirect back to the frontend and tell it to use external_auth
        return 301 /?external_auth=1;
    }
}

Format it:

<script>
    window.externalApp = {
    
    
        getExternalAuth: function() {
    
    
            window.externalAuthSetToken(true, {
    
    
                "access_token": "第一步创建长期的令牌",
                "expires_in": 248832000
            });
        },
        revokeExternalAuth: function() {
    
    
            window.externalAuthRevokeToken(false);
        }
    };
</script>

Implementation process

  1. Users access port 86 of nginx
  2. nginx will first request the address http://xxx/sso/auth for authentication, and if the response code is 200, it will forward the request to the hass address http://localhost:8123
  3. If the authentication fails and an unauthorized response code such as 401 is returned, nginx will directly return a 401 error to the browser, and access to hass is prohibited. Please log in to sso for authentication first.
  4. Here nginx replaces the content of the response when proxying hass, and adds the content sub_filterin it <head><script>window.externalApp........ This is to tell hass to perform external authorization authentication. It will execute the getExternalAuth function to obtain the token, and return my long-term token directly here. Because we have done authentication in nginx, we will no longer authenticate here.

Guess you like

Origin blog.csdn.net/weixin_48835367/article/details/131972193
sso