Programatic username/password access with KeyCloak using external IDP brokering(通过使用外部IDP代理的KeyCloak进行程序化用户名/密码访问)
问题描述
我正在使用Identity Brokering功能和外部IdP。因此,用户登录到外部IdP用户界面,然后KeyCloak Broker客户端从外部IdP接收JWT令牌,KeyCloak提供JWT供我们访问资源。我已经设置了Default Identitiy Provider功能,以便在登录时向用户显示外部IDP登录屏幕。这意味着用户及其密码存储在外部IdP上。
当我需要在测试中以编程方式使用"Direct Access Grant"(资源所有者密码授予)登录时,会出现这个问题。由于密码没有存储在KeyCloak上,登录时我总是从KeyCloak收到401未经授权的错误。当我试图更改用户密码时,它开始起作用了,所以问题是用户密码没有在KeyCloak上提供,并且使用"Direct Access Grant"KeyCloak在编程登录时不会调用外部IDP。
我使用以下代码来获取访问令牌,但每次传递有效的用户名/密码时都会收到401错误。org.keycloak.authorization.client.util.HttpResponseException: Unexpected response from server: 401 / Unauthorized
已为该客户端启用直接访问授权。
public static String login(final Configuration configuration) {
final AuthzClient authzClient = AuthzClient.create(configuration);
final AccessTokenResponse accessTokenResponse = authzClient.obtainAccessToken(USERNAME, PASSWORD);
return accessTokenResponse.getToken();
}
有没有办法解决这个问题?例如,在"Direct Access Grant"上调用Identity Broker,以便KeyCloak向我们提供其有效令牌?
推荐答案
问题在于KeyCloak没有来自初始身份提供者的有关密码的信息。它们具有token exchange feature,应用于编程令牌交换。
External Token to Interanal Token Exchange应使用它。
下面是一个用Python语言编写的示例代码,它可以执行此操作(只需在占位符中放置正确的值):
def login():
idp_access_token = idp_login()
return keycloak_token_exchange(idp_access_token)
def idp_login():
login_data = {
"client_id": <IDP-CLIENT-ID>,
"client_secret": <IDP-CLIENT-SECRET>,
"grant_type": <IDP-PASSWORD-GRANT-TYPE>,
"username": <USERNAME>,
"password": <PASSWORD>,
"scope": "openid",
"realm": "Username-Password-Authentication"
}
login_headers = {
"Content-Type": "application/json"
}
token_response = requests.post(<IDP-URL>, headers=login_headers, data=json.dumps(login_data))
return parse_response(token_response)['access_token']
def keycloak_token_exchange(idp_access_token):
token_exchange_url = <KEYCLOAK-SERVER-URL> + '/realms/master/protocol/openid-connect/token'
data = {
'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange',
'subject_token': idp_access_token,
'subject_issuer': <IDP-PROVIDER-ALIAS>,
'subject_token_type': 'urn:ietf:params:oauth:token-type:access_token',
'audience': <KEYCLOAK-CLIENT-ID>
}
response = requests.post(token_exchange_url, data=data,
auth=(<KEYCLOAK-CLIENT-ID>, <KEYCLOAK-CLIENT-SECRET>))
logger.info(response)
return parse_response(response)['access_token']
这篇关于通过使用外部IDP代理的KeyCloak进行程序化用户名/密码访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:通过使用外部IDP代理的KeyCloak进行程序化用户名/密码访问
基础教程推荐
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01