从(移动)应用程序调用Keycloak的注销端点时遇到问题.
支持此方案的文档中所述:
/境界/ {领域名} /协议/ OpenID的连接/注销
注销端点注销经过身份验证的用户.
可以将用户代理重定向到端点,在这种情况下,将注销活动用户会话.之后,用户代理将重定向回应用程序.
端点也可以由应用程序直接调用.要直接调用此端点,需要包含刷新令牌以及验证客户端所需的凭据.
我的请求有以下格式:
POST http://localhost:8080/auth/realms/<my_realm>/protocol/openid-connect/logout
Authorization: Bearer <access_token>
Content-Type: application/x-www-form-urlencoded
refresh_token=<refresh_token>
Run Code Online (Sandbox Code Playgroud)
但总是会出现此错误:
HTTP/1.1 400 Bad Request
Connection: keep-alive
X-Powered-By: Undertow/1
Server: WildFly/10
Content-Type: application/json
Content-Length: 123
Date: Wed, 11 Oct 2017 12:47:08 GMT
{
"error": "unauthorized_client",
"error_description": "UNKNOWN_CLIENT: Client was not identified by any client authenticator"
}
Run Code Online (Sandbox Code Playgroud)
如果我提供了access_token,Keycloak似乎无法检测到当前客户端的身份事件.我使用相同的access_token来访问其他Keycloak的API而没有任何问题,例如userinfo (/ auth/realms // protocol/openid-connect/userinfo).
我的请求是基于这个Keycloak的问题.该问题的作者得到了它的工作,但这不是我的情况.
我正在使用Keycloak 3.2.1.Final.
你有同样的问题吗?你知道如何解决它吗?
Man*_* Ha 20
最后,我通过查看Keycloak的源代码找到了解决方案:https://github.com/keycloak/keycloak/blob/9cbc335b68718443704854b1e758f8335b06c242/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ LogoutEndpoint.java#L169.它说:
如果客户端是公共客户端,则必须包含"client_id"表单参数.
所以我缺少的是client_id表单参数.我的要求应该是:
POST http://localhost:8080/auth/realms/<my_realm>/protocol/openid-connect/logout
Authorization: Bearer <access_token>
Content-Type: application/x-www-form-urlencoded
client_id=<my_client_id>&refresh_token=<refresh_token>
Run Code Online (Sandbox Code Playgroud)
会话应该被正确销毁.
小智 15
最后。这对我有用。我进行了 REST 调用,如下所示:
标题:
{
"Authorization" : "Bearer <access_token>",
"Content-Type" : "application/x-www-form-urlencoded"
}
Run Code Online (Sandbox Code Playgroud)
请求正文:
{
"client_id" : "<client_id>",
"client_secret" : "<client_secret>",
"refresh_token" : "<refresh_token>"
}
Run Code Online (Sandbox Code Playgroud)
方法:
POST
Run Code Online (Sandbox Code Playgroud)
网址:
<scheme>://<host>:<port>/auth/realms/<realmName>/protocol/openid-connect/logout
Run Code Online (Sandbox Code Playgroud)
我收到 200 作为响应...如果您做错任何事情,您将收到 401 或 400 错误。调试这个问题非常困难。顺便说一句,我的钥匙斗篷版本是12.0.4
如果帖子不清楚或者您需要更多信息,请告诉我。
Dmi*_*zin 12
适用于 Keycloak 6.0。
只是为了清楚起见:我们确实使 refreshToken 过期,但 accessToken 在“访问令牌寿命”时间内仍然有效。下次用户尝试通过刷新令牌更新访问令牌时,Keycloak 返回 400 Bad request,应该捕获什么并将其作为 401 Unauthorized 响应发送。
public void logout(String refreshToken) {
try {
MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
requestParams.add("client_id", "my-client-id");
requestParams.add("client_secret", "my-client-id-secret");
requestParams.add("refresh_token", refreshToken);
logoutUserSession(requestParams);
} catch (Exception e) {
log.info(e.getMessage(), e);
throw e;
}
}
private void logoutUserSession(MultiValueMap<String, String> requestParams) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestParams, headers);
String url = "/auth/realms/my-realm/protocol/openid-connect/logout";
restTemplate.postForEntity(url, request, Object.class);
// got response 204, no content
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18823 次 |
| 最近记录: |