我正在尝试将 keycloak-gatekeeper 设置为 docker 容器前面的反向代理,以便提供针对容器的身份验证和授权。我使用 FusionAuth 作为 OIDC 兼容的身份提供程序,并设法使用授权流程让 keycloak-getekeeper 使用它。 当我尝试根据用户的角色或组成员身份限制哪些用户可以访问资源时,问题就出现了。
目前,所有请求均被拒绝。当我查看服务器上的日志时,我可以看到以下消息:
1.5548202388823931e+09 info keycloak-gatekeeper/middleware.go:90 client request {"latency": 0.039427852, "status": 403, "bytes": 0, "client_ip": "127.0.0.1:40866", "method": "GET", "path": "/"}
1.5548202614442139e+09 error keycloak-gatekeeper/middleware.go:108 no session found in request, redirecting for authorization {"error": "authentication session not found"}
1.5548202614443152e+09 info keycloak-gatekeeper/middleware.go:90 client request {"latency": 0.000108426, "status": 307, "bytes": 95, "client_ip": "127.0.0.1:40866", "method": "GET", "path": "/"}
1.5548202614823494e+09 debug keycloak-gatekeeper/handlers.go:88 incoming authorization request from client address {"access_type": "", "auth_url": "https://identity.***********.io/oauth2/authorize?client_id=********&redirect_uri=https%3A%2F%2F********.io%2Foauth%2Fcallback&response_type=code&scope=openid+email+profile&state=********", "client_ip": "127.0.0.1:40866"}
1.554820261482426e+09 info keycloak-gatekeeper/middleware.go:90 client request {"latency": 0.000132558, "status": 307, "bytes": 298, "client_ip": "127.0.0.1:40866", "method": "GET", "path": "/oauth/authorize"}
1.5548203051960323e+09 info keycloak-gatekeeper/handlers.go:167 issuing access token for user {"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3c4f535159494f594e7c5853515d5552125f5351" rel="noreferrer noopener nofollow">[email protected]</a>", "expires": "2019-04-09T15:31:45Z", "duration": "59m59.803970144s"}
1.5548203051961453e+09 info keycloak-gatekeeper/middleware.go:90 client request {"latency": 0.099124835, "status": 307, "bytes": 37, "client_ip": "127.0.0.1:40866", "method": "GET", "path": "/oauth/callback"}
1.5548203052413428e+09 debug keycloak-gatekeeper/session.go:51 found the user identity {"id": "5f165d68-9350-47e6-9152-d76260cabd7c", "name": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0c7f636169797f697e4c6863616d6562226f6361" rel="noreferrer noopener nofollow">[email protected]</a>", "email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7a4b8bab2a2a4b2a597b3b8bab6beb9f9b4b8ba" rel="noreferrer noopener nofollow">[email protected]</a>", "roles": "", "groups": ""}
1.5548203052417035e+09 warn keycloak-gatekeeper/middleware.go:307 access denied, invalid roles {"access": "denied", "email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="493a26242c3c3a2c3b092d2624282027672a2624" rel="noreferrer noopener nofollow">[email protected]</a>", "resource": "/*", "roles": "role-1,role-3"}
1.5548203052417736e+09 info keycloak-gatekeeper/middleware.go:90 client request {"latency": 0.000509757, "status": 403, "bytes": 0, "client_ip": "127.0.0.1:40866", "method": "GET", "path": "/"}
据我所知,我拒绝的原因是因为角色尚未填充。 我还运行了一个客户端来为用户获取 JWT(通过隐式流程),该用户返回时看起来如下所示:
{
"aud": "************************",
"exp": 1554822076,
"iat": 1554818476,
"iss": "https://identity.*******.io",
"sub": "****************",
"authenticationType": "PASSWORD",
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5625393b33232533241632393b373f387835393b" rel="noreferrer noopener nofollow">[email protected]</a>",
"email_verified": true,
"applicationId": "*****************",
"roles": [
"role-1",
"role-3"
]
}
从中,我可以看到用户处于正确的角色。
目前我有点不知道问题出在哪里,或者如何更详细地调试 keycloak-gatekeeper 实例
最佳答案
看起来 keycloak-gatekeeper 只能处理 keycloak 提供的 token 中的领域和客户端角色 ( https://github.com/keycloak/keycloak-gatekeeper/blob/master/user_context.go )
以下是从 token 中提取角色的相关代码:
// @step: extract the realm roles
var roleList []string
if realmRoles, found := claims[claimRealmAccess].(map[string]interface{}); found {
if roles, found := realmRoles[claimResourceRoles]; found {
for _, r := range roles.([]interface{}) {
roleList = append(roleList, fmt.Sprintf("%s", r))
}
}
}
// @step: extract the client roles from the access token
if accesses, found := claims[claimResourceAccess].(map[string]interface{}); found {
for name, list := range accesses {
scopes := list.(map[string]interface{})
if roles, found := scopes[claimResourceRoles]; found {
for _, r := range roles.([]interface{}) {
roleList = append(roleList, fmt.Sprintf("%s:%s", name, r))
}
}
}
}
这可以解释为什么我的 token 中的声明没有出现
关于openid-connect - 针对外部 OIDC 提供商进行身份验证时,Keycloak-Gatekeeper 不会填充角色或组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55595813/