我有一个nginx/openresty客户端到keycloack服务器,使用openid进行授权。
我正在使用
lua-resty-openidc
以允许访问代理后面的服务。
我在两个不同的领域为不同的服务创建了两个客户端。
问题是,在用户在第一个领域通过身份验证后,例如。
https://<my-server>/auth/realms/<realm1>/protocol/openid-connect/auth?response_type=code&client_id=openresty&state=...........
,他可以直接访问其他服务
realm2
也。
这里发生了什么事?我如何确保用户只能访问其身份验证所针对的领域的客户端?
我如何确保注销后,用户在重新登录之前将无法再访问?
[编辑详细信息]
这两个服务的nginx.conf如下。
用户首先访问
https://<my-server>/service_1/
并被重定向到keycloack以提供realm1的密码。他提供了它,并且能够访问service_1。
然而,如果在那之后他试图进入
https://<my-server>/service_2/
,他不再需要进行身份验证,但可以登录,尽管service2是关于不同领域的客户端,具有不同的client_secret!
.....
位置/服务_1/{
access_by_lua_block {
local opts = {
redirect_uri_path = "/service_1/auth", -- we are send here after auth
discovery = "https://<my-server>/keycloak/auth/realms/realm1/.well-known/openid-configuration",
client_id = "openresty",
client_secret = "<client1-secret>",
session_contents = {id_token=true} -- this is essential for safari!
}
-- 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
}
# I disabled caching so the browser won't cache the site.
expires 0;
add_header Cache-Control private;
proxy_pass http://<server-for-service1>:port1/foo/;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
..........................
location /service_2/ {
access_by_lua_block {
local opts = {
redirect_uri_path = "/service_2/auth", -- we are send here after auth
discovery = "https://<my-server>/keycloak/auth/realms/realm2/.well-known/openid-configuration",
client_id = "openresty",
client_secret = "client2-secret",
session_contents = {id_token=true} -- this is essential for safari!
}
-- 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
}
# I disabled caching so the browser won't cache the site.
expires 0;
add_header Cache-Control private;
proxy_pass http://<server-for-service2>:port2/bar/;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
[编辑详细信息2]
我使用的是lua-resty openidc 1.7.2版本,但根据两个版本代码的差异,我写的所有内容都应该代表1.7.4。
我可以从调试级别日志中清楚地看到,会话是在第一次访问期间创建的,然后在第二个领域上重用,这是错误的,因为第二次访问仍然有第一个领域的令牌。。。以下是授权内容
realm2
看起来像…:
2021/04/28 12:56:41 [debug] 2615#2615: *4617979 [lua] openidc.lua:1414: authenticate(): session.present=true, session.data.id_token=true, session.data.authenticated=true, opts.force_reauthorize=nil, opts.renew_access_token_on_expiry=nil, try_to_renew=true, token_expired=false
2021/04/28 12:56:41 [debug] 2615#2615: *4617979 [lua] openidc.lua:1470: authenticate(): id_token={"azp":"realm1","typ":"ID","iat":1619614598,"iss":"https:\/\/<myserver>\/keycloak\/auth\/realms\/realm1","aud":"realm1","nonce":"8c8ca2c4df2...b26"
,"jti":"1c028c65-...0994f","session_state":"0e1241e3-66fd-4ca1-a0dd-c0d1a6a5c708","email_verified":false,"sub":"25303e44-...e2c1757ae857","acr":"1","preferred_username":"logoutuser","auth_time":1619614598,"exp":1619614898,"at_hash":"5BNT...j414r72LU6g"}