openresty 集成 keycloak-oauth-oidc
keycloak 是一个比较全,而且比较方便的sso 解决方案,同时为我们提供了灵活的扩展特性
备注: 测试使用docker-compose 运行,对于keycloak 使用pg 数据库做为后端存储
环境准备
- docker-compose文件
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"
- nginx 配置
dockerfile: 主要是添加lua 包
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 以及添加一个可以登陆的用户)
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;
}
}
}
- lua 代码说明
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
keycloak 配置信息
- realm
*client
- user
启动&&测试
- 启动
docker-compose up -d
- 本地hosts 配置
因为使用了dns 地址
/etc/hosts
添加
127.0.0.1 auth
- 测试
打开 http://localhost:8090 会重定向到keycloak 的登陆页面,输入添加的用户信息
session 信息
说明
注意我nginx.conf 中注释的说明,因为lua-resty-openidc 使用了lua-resty-session 但是lua-resty-session 在关闭lua cache 的时候
每次session secreet 会重新生成,所以比较靠谱的方便是指定一个session secret ,参考上边nginx 配置
参考资料
https://developers.redhat.com/blog/2018/10/08/configuring-nginx-keycloak-oauth-oidc/
https://github.com/rongfengliang/keycloak-openresty-openidc