keycloak 是一個比較全,並且比較方便的sso 解決方案,同時爲咱們提供了靈活的擴展特性
備註: 測試使用docker-compose 運行,對於keycloak 使用pg 數據庫作爲後端存儲html
version: "3" services: openresty: build: context: ./ dockerfile: ./Dockerfile ports: - "8090:80" volumes: - "./nginx_lua/:/opt/app/" - "./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf" auth: image: jboss/keycloak ports: - "8080:8080" environment: - "KEYCLOAK_USER=dalong" - "KEYCLOAK_PASSWORD=dalongrong" - "DB_VENDOR=postgres" - "DB_ADDR=postgres" - "DB_DATABASE=postgres" - "DB_USER=postgres" - "DB_PASSWORD=dalong" - "PROXY_ADDRESS_FORWARDING=true" postgres: image: postgres:9.6 ports: - "5432:5432" environment: - "POSTGRES_PASSWORD:dalong"
FROM openresty/openresty:alpine-fat LABEL author="1141591465@qq.com" RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-openidc EXPOSE 80
nginx.conf: 配置lua-resty-openidc 相關參數(注意realm 須要建立,同時須要建立client 以及添加一個能夠登錄的用戶)nginx
worker_processes 1; user root; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; lua_code_cache off; lua_need_request_body on; gzip on; # cache for discovery metadata documents lua_shared_dict discovery 1m; # cache for JWKs lua_shared_dict jwks 1m; resolver 127.0.0.11 ipv6=off; real_ip_header X-Forwarded-For; real_ip_recursive on; lua_package_path '/opt/app/?.lua;;'; server { listen 80; server_name localhost; charset utf-8; ## 此參數比較重要,由於爲了方便我關閉了lua code cache set $session_secret 623q4hR325t36VsCD3g567922IC0073T; default_type text/html; access_by_lua_block { require("oidc/acc")() } expires 0; add_header Cache-Control private; location / { default_type text/plain; index index.html index.htm; } location /redirect_uri { default_type text/plain; content_by_lua_block { ngx.req.read_body() require("oidc/init")() } } location = /favicon.ico { root /opt/app/static; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
local cjson = require("cjson") function init() -- 配置參數從keycloak系統獲取 local opts = { redirect_uri_path = "/redirect_uri", accept_none_alg = true, discovery = "http://auth:8080/auth/realms/nginx/.well-known/openid-configuration", client_id = "nginx", client_secret = "1fb2d094-3a66-4c30-9cdb-f4210939fb1d", redirect_uri_scheme = "http", logout_path = "/logout", redirect_after_logout_uri = "http://auth:8080/auth/realms/nginx/protocol/openid-connect/logout?redirect_uri=http://localhost:8090/", redirect_after_logout_with_id_token_hint = false, session_contents = {id_token = true} } -- call introspect for OAuth 2.0 Bearer Access Token validation local res, err = require("resty.openidc").authenticate(opts) if err then ngx.status = 403 ngx.say(err) ngx.exit(ngx.HTTP_FORBIDDEN) end -- ngx.say(cjson.encode(res)) end return init
docker-compose up -d
/etc/hosts 添加 127.0.0.1 auth
注意我nginx.conf 中註釋的說明,由於lua-resty-openidc 使用了lua-resty-session 可是lua-resty-session 在關閉lua cache 的時候
每次session secreet 會從新生成,因此比較靠譜的方即是指定一個session secret ,參考上邊nginx 配置git
https://developers.redhat.com/blog/2018/10/08/configuring-nginx-keycloak-oauth-oidc/
https://github.com/rongfengliang/keycloak-openresty-openidcgithub