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

posted on 2019-01-29 14:01  荣锋亮  阅读(3546)  评论(5编辑  收藏  举报

导航