使用oauth2-proxy给你的页面添加一个认证

简介

有很多页面都是没有登录验证的,比如prometheus,skywalking等,这个时候就可以使用oauth2-proxy去添加验证,oauth2-proxy本质是一个反向代理服务器,你可以直接把服务放到oauth2-proxy后面,或者在nginx之后放oauth2-proxy通过它来代理到你的服务中

项目地址

https://github.com/oauth2-proxy/oauth2-proxy

支持对接的服务

  • Google default
  • Azure
  • ADFS
  • Facebook
  • GitHub
  • Keycloak
  • GitLab
  • LinkedIn
  • Microsoft Azure AD
  • OpenID Connect
  • login.gov
  • Nextcloud
  • DigitalOcean
  • Bitbucket
  • Gitea

实验环境

这里我选择直接对接github,其他的服务对接也都是类似的,因为我原先就是有一个nginx的,所以我会在应用和nginx之间添加一个oauth2-proxy

创建github应用

https://github.com/settings/developers

在这个页面去创建一个github应用拿到Client ID和Client secrets

Homepage URL直接写你的oauth2-proxy的地址,比如

https://oauth.xxxx.com/

Authorization callback URL填写oauth2-proxy的回调接口

https://oauth.xxxx.com/oauth2/callback

配置nginx

因为我的oauth2-proxy是放在nginx之后的,所以首先要配置的是oauth2-proxy的反向代理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
server {
    listen       443 ssl http2;
    server_name  oauth.xxxx.com;
    ssl_certificate cert/cloudflare/cloudflare.pem;
    ssl_certificate_key cert/cloudflare/cloudflare.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    #表示使用的加密套件的类型。
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
    ssl_prefer_server_ciphers on;

    location / {
      proxy_set_header Host       $host;
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_pass http://127.0.0.1:4180/;
      access_log logs/oauth.log main;
    }
}

配置启动oauth2-proxy

首先是docker-compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
version: '3.0'
services:
  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:v7.2.1
    command: --config /oauth2-proxy.cfg
    ports: 
      - 4180:4180
    volumes:
      - "./oauth2-proxy-nginx.cfg:/oauth2-proxy.cfg"
    restart: always

之后是配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
http_address="0.0.0.0:4180"
cookie_secret="td22915FBBk1Q3dsdJCCff1cdsdFU5zJgLm2XHsLDYQ="
provider="github"
email_domains="gmail.com"
client_id="7e3637ae8edd28a2"
client_secret="226ba8bc4a1571426c58bcf28c"
scope = "user:email"
reverse_proxy=true
cookie_secure="false"
cookie_domains=".xxx.cn"
whitelist_domains=".xxx.cn"

`cookie_secret可以使用下面的命令随便生成一个

openssl rand -base64 32 | tr -- '+/' '-_'

这个是用来加密cookie的

provider就是你用的OAuth Provider,这里就和之前说的一样写github

email_domains这个是用来验证制定域名的邮箱,可以填写*来表示验证任何邮箱

client_idclient_secret就是创建github应用的时候拿到的

scope允许授权服务器或用户修改授予应用程序的范围,这个保持默认就好了

reverse_proxy表示你是不是在反向代理后面,因为在nginx后面所以写true

cookie_secure 设置安全的cookie标志,文档说仅限https,因为内网都是http的所以配置为false

cookie_domains cookie域名

whitelist_domains 允许身份验证之后重定向的域名

配置完成之后使用compose启动

配置应用的反向代理

首先确认你的nginx拥有--with-http_auth_request_module这个模块,没有的可以编译进去

--prefix=/data/nginx/nginx --with-stream --with-http_ssl_module --with-http_stub_status_module --add-module=/data/nginx/nginx-src/nginx-module-vts --with-http_realip_module --with-http_v2_module --add-module=/data/nginx/nginx-src/ngx_brotli --with-http_auth_request_module

之后我的示例配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
server {
    listen       443 ssl http2;
    server_name  app.xxx.cn;
    ssl_certificate cert/cloudflare/cloudflare.pem;
    ssl_certificate_key cert/cloudflare/cloudflare.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    #表示使用的加密套件的类型。
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
    ssl_prefer_server_ciphers on;

    auth_request /internal-auth/oauth2/auth;

    error_page 401 = https://oauth.xxx.com/oauth2/sign_in?rd=$scheme://$host$request_uri;

    location /{


        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_pass http://127.0.0.1:3002;
        access_log logs/share.log main;
        client_max_body_size 1000m;


    }

    location /internal-auth/ {
      internal; # Ensure external users can't access this path

      proxy_set_header Host       $host;
      proxy_set_header X-Real-IP  $remote_addr;

      proxy_pass http://127.0.0.1:4180/;
    }



}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    auth_request /internal-auth/oauth2/auth;

    error_page 401 = https://oauth.xxx.com/oauth2/sign_in?rd=$scheme://$host$request_uri;

    location /internal-auth/ {
      internal; # Ensure external users can't access this path

      proxy_set_header Host       $host;
      proxy_set_header X-Real-IP  $remote_addr;

      proxy_pass http://127.0.0.1:4180/;
    }

这个是要加的,首先请求/internal-auth/这个路径,如果是401的话那就重定向到oauth2-proxy认证完成之后再重定向到应用

401重定向的地址有下面两个

https://oauth.xxx.com/oauth2/sign_in?rd=$scheme://$host$request_uri;

http://oauth2-proxy.oauth2-proxy.localhost/oauth2/start?rd=$scheme://$host$request_uri;

/oauth2/sign_in 可以到oauth2-proxy登录页面

/oauth2/start 会直接跳过oauth2-proxy登录页面到github的认证页面

最后

访问你的应用,不出问题的话会直接跳转到oauth2-proxy的认证界面,登陆完github之后就可以直接进入你的应用了。

再说几句

oauth2-proxy 支持使用redis存储session,默认我们像上面这样配置完成之后重启oauth2-proxy你需要重新登录GitHub

欢迎关注我的博客 www.bboy.app

Have Fun