Configuring keycloak as IDP in another keycloak - keycloak

I am trying to configure a keycloak as an IDP in another keycloak. In my test setup there are 2 keycloak containers - keycloak-1 and keycloak-2.
In keycloak-1, I have created an openid client called idp-client. The configuration exported as JSON is shown below,
{
"clientId": "idp-client",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://localhost:8081/auth/realms/master/broker/oidc/endpoint"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"role_list",
"profile",
"roles",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
In keycloak-2, I have added keycloak-1 as an identity provider. I have attached the images of the configuration for reference.
Now when I try to login to keycloak-2 using keycloak-1's user, after successful login, I am redirected to keycloak-2's but to an error page, its showing "Unexpected error when authenticating with identity provider"
Stacktrace in the keycloak-2's terminal is as below,
keycloak2_1 | 08:21:17,079 TRACE [org.keycloak.events] (default task-10) type=CODE_TO_TOKEN_ERROR, realmId=master, clientId=idp-client, userId=null, ipAddress=127.0.0.1, error=invalid_client_credentials, grant_type=authorization_code, requestUri=http://localhost:8080/auth/realms/master/protocol/openid-connect/token, cookies=[]
...
...
keycloak2_1 | 08:21:17,081 TRACE [org.keycloak.events] (default task-12) type=LOGIN_ERROR, realmId=master, clientId=null, userId=null, ipAddress=172.21.0.1, error=identity_provider_login_failure, requestUri=http://localhost:8081/auth/realms/master/broker/oidc/endpoint?state=MOz5_i2-SpoSLRtS4IWkXtUBsSzGciBysUrdYq8gGy0.k0e5WlQElRw.security-admin-console&session_state=1cc90330-cf3c-45c3-a44e-53fc71b17bb1&code=be12828b-3408-4822-b275-31afeb1c0405.1cc90330-cf3c-45c3-a44e-53fc71b17bb1.eb068c43-9f4e-45b7-b2e8-ac346f139141, cookies=[KEYCLOAK_SESSION_LEGACY=master/ce30941f-407f-4344-9019-58d2f26ea832/1cc90330-cf3c-45c3-a44e-53fc71b17bb1, PrivacyPolicy=accepted, KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxNjgzNzMzNi1mMTA3LTRiMTktODk1Yi0wNWJmZDliZGIzYTUifQ.eyJleHAiOjE2MDk3ODQ0NzcsImlhdCI6MTYwOTc0ODQ3NywianRpIjoiNTQ3YmRlZGQtOGQyYy00MTJkLWJhMzYtZjkyNzAwNjlhYzQxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6ImNlMzA5NDFmLTQwN2YtNDM0NC05MDE5LTU4ZDJmMjZlYTgzMiIsInR5cCI6IlNlcmlhbGl6ZWQtSUQiLCJzZXNzaW9uX3N0YXRlIjoiMWNjOTAzMzAtY2YzYy00NWMzLWE0NGUtNTNmYzcxYjE3YmIxIiwic3RhdGVfY2hlY2tlciI6IkZFT3psWkRScXhqREVVOGV6MFd6MU5menZGYU1jNHRzV1J4TnlrNUc5NDQifQ.YeBB6vJYZ9Z4IUXY2-og17EMRodUdeqTBTQ31pY3P1s, AUTH_SESSION_ID_LEGACY=1cc90330-cf3c-45c3-a44e-53fc71b17bb1.4c93e8da0ca1]
In keycloak-1, the user is logged in i.e. a session is shown for idp-client.

The mentioned issue was rectified once the SSL was enabled.

Related

Keycloak SAML Client is not showing the login screen

I have created a realm in Keycloak named SAML-Demo-Py
In the realm I have created a SAML client with these configuration
{
"clientId": "http://localhost:8081/python-app",
"name": "test-client-saml",
"description": "",
"rootUrl": "",
"adminUrl": "http://localhost:8081/cgi-bin/saml-consumer.py",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://localhost:8081/cgi-bin/saml-consumer.py"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "saml",
"attributes": {
"saml_assertion_consumer_url_redirect": "http://localhost:8081/cgi-bin/saml-consumer.py",
"saml.force.post.binding": "true",
"saml.server.signature.keyinfo.ext": "false",
"saml.signing.certificate": "MIICzzCCAbcCBgGDSplRlDANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBodHRwOi8vbG9jYWxob3N0OjgwODEvcHl0aG9uLWFwcDAeFw0yMjA5MTcwODM2NDVaFw0zMjA5MTcwODM4MjVaMCsxKTAnBgNVBAMMIGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MS9weXRob24tYXBwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve0sgrdPWvcKiRJ5UPcpa301aiIO7F7KDKnMDtxgY2EE47z8XS5TUvvySa75L0phxZQv+iqYSV1HlUkgJQiax3fg7JgxJ+BY3ss9Dz/m9x7stErFoMXeH+Bhdk9H7hUojlRqxn8qU7ZwInENvw8hlzTgouc5hqqBaQybXqtlmJi6HWAH/3Ck6jCd+P6pjIaGrQpYxpmpmPKbhRnovZWgL6KqdnoEl1thEcPAEbXE7HiB6h4z9HdF2EWx/8U7HE/qCq2m2lPsKn2OnJk2ejDqa5SyTBXRqeqS8sG70VXrotEtJVVuPJCFvGy8r7mq0bVX/83y+PyEpppsJMMtockdgwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBEDptd2Goi1XFKur3dpRHyOW9zxs96gGGllrcnQZCtZjVEb31Jibr0HFDftHR22hQV1mbQLokNk8k0on7tJvsOIdXv3459gkZyouYSmYpDTvfCi3YUgdxVrDiHzwaN6uIjqXeDeI08LmH2xDZwac46vqJyqx3QI/r84qmWR2Nil/7DnJegVWyr961GWm0HH6BpweZZ5QbEw0UHihqWDthgX4BAmVnRPm9fHebIa3/7AUqodh8hoRDJcaDiyLB+V8nUPD6vLwgFgiLSqLSPaJ0OSzBvz3cpNLL1PVkFVaoQZ7W3FX6Ruvz0Bj/piQ+h2fnX4NMkj33f6CyhJTGSfbnk",
"saml$server$signature$keyinfo$ext": "false",
"saml.signature.algorithm": "RSA_SHA256",
"saml.client.signature": "false",
"saml.force.name.id.format": "false",
"saml.signing.private.key": "MIIEowIBAAKCAQEAve0sgrdPWvcKiRJ5UPcpa301aiIO7F7KDKnMDtxgY2EE47z8XS5TUvvySa75L0phxZQv+iqYSV1HlUkgJQiax3fg7JgxJ+BY3ss9Dz/m9x7stErFoMXeH+Bhdk9H7hUojlRqxn8qU7ZwInENvw8hlzTgouc5hqqBaQybXqtlmJi6HWAH/3Ck6jCd+P6pjIaGrQpYxpmpmPKbhRnovZWgL6KqdnoEl1thEcPAEbXE7HiB6h4z9HdF2EWx/8U7HE/qCq2m2lPsKn2OnJk2ejDqa5SyTBXRqeqS8sG70VXrotEtJVVuPJCFvGy8r7mq0bVX/83y+PyEpppsJMMtockdgwIDAQABAoIBABjRKm1ELarZt/c0QkTpnvBsMnQVUjThp+4iq8bPVgr2TPDDK4izenDP+hdVtTrQMdli5Sf/s9l2RlnD7d7Y8nyY9fuEYXvv7Tzjeq2I8JGe6VgfoxZAdKdepu2SK3h5LEz4y+D3Ed1Ra/KcKisqe32qC6ZNp28ozXMgEhc7NzHKnOxKA0IXFzuT6cDJgJ8TQfa2K9dGgjEE9GTCCxnZEvdf17sEc4zVMJDDcE4Rorv0mZeN1QRXVSpnW1q0vFh1CvH1H9oBCUey8cElQybARTDbMJJWgHCdd29EbilmlyB4TFI34tcaKZUlvL3sT8fvRyV6yLL0M0mqVWYxhu24naUCgYEA/WKH8G6SsM+LhC2oVJWUSDicpDNNEi2Av2FZOSg7Vbqj53/t69kSPWv0Rp0o7Bz55xwxH+n6PjUEvHyiS3UBIW6kS81av1H8Gle/1XpopHEY4aX47KCdF1Wc0yq8l5ii+oFZt3GcS1egDFPiQgyo2lhlrrQ4mckcSZF3pdd8UTUCgYEAv+L6qdXxPZvyzRgsRfhmVl8FKdKPYFqBWQgh2Lx21J16T8jRhjFfJP6NNi2JupWrQB2JdA5sivx81GMxExo5j8P1VQm/g/c3I2bxb1kYDE77x6KJzmr0i7hK0SEGCcP51EdVpjtPzcdG3st3GT5UClvZ+rTfO87e6n4pdlMUgtcCgYBUre8cTPe9Gz9XByMwUWTi1fiTb4mcP5S9YL0+utFJjzxji39pyHuuBzv1tWQNtIlX0TYhokI9M97HVyet7AZas+04YAKp2a5U52p235fFDP7xulP8UJjvSW9Fqwyn5RzidwQSqGdBTqFwPUBqLmznu48P2a7oxisr8u93fxJO2QKBgG0fkdl/139n7n6AXr0z9E7uHquYGP18us5893KgSxvCqsowtCcScL9DG99Rql+3ufnuUjrz8PpheEP4XPI2GcIOeLhxoL5Vmr/BTVA7ZJerWzg+0QvYe1Xx6mpf02U+VBdKsgSk+k9WIpGVOBfdAEIb1izjK4iBrve/46hsut9lAoGBAKeKxXlH45BTuRg/Rcp60TTV4i+Aed0ApTmvYU22XasXRfrFsauLaxUkCP0x0hvdVx+cR37Jo9Nfw9DmplzHLVMI6STzracLuhjf0HKVS6XSJa5l4VpsmkJaWxyqdrm91OXnOOizTf6pOoRFoFI21u7ZKqMoEcaqrCOIwqv21qpa",
"saml.allow.ecp.flow": "false",
"saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer": "NONE",
"saml.assertion.signature": "true",
"saml.encrypt": "false",
"login_theme": "keycloak",
"saml_assertion_consumer_url_post": "http://localhost:8081/cgi-bin/saml-consumer.py",
"saml$server$signature": "true",
"saml.server.signature": "true",
"saml.artifact.binding.identifier": "90y02x5M6keohgaOI7l3D0ZpdfU=",
"saml$server$signature$keyinfo$xmlSigKeyInfoKeyNameTransformer": "NONE",
"saml.artifact.binding": "false",
"saml_force_name_id_format": "false",
"saml.authnstatement": "true",
"display.on.consent.screen": "false",
"saml_name_id_format": "username",
"saml.onetimeuse.condition": "false",
"saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"role_list"
],
"optionalClientScopes": [],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
I have a running python dummy app which will act as ACS.
This is the SAML Request which will be send from the browser in the form of
<IDP-sso-url>?SAMLRequest=<encoded-same-request>
which results in
http://localhost:8080/realms/SAML-Demp-Py?SAMLRequest=lVLLTsMwEPyVyHfXSZpCayWVSiNEJEBRKRy4INdZqIVjB6%2FD4%2B9xUpDKBcHNK8%2FMzow2R9Hqjq96vzcbeOkBffTeaoN8%2FChI7wy3AhVyI1pA7iW%2FWV1d8nQS885Zb6XV5ED5HSwQwXllDTla8GfK6vu5tgb7FtwNuFcl4XZzWZC99x1nTFsp9N6i5%2FN4HjMHQrfIBjVaQtvR%2BoPtnH0Gx4bVVDUd9SEvA9N0VhlPojKMyohhzz9USXRunYSxw4I8Co1AoqosSFU%2BxMluOltAQuOTpKEZwIyKTIYxyzKxkDJtxGkAI%2FZQGfTC%2BIKkcZrSeEGT022S8GnM05PJdDG%2FJ1H9VfiZMo0yT7%2B3tzuAkF9stzXdQKMcyBDyDhyOAQOILPOhCz4acMs%2FR87ZMS0%2FHNF1sFCVtdVKfkQrre3bOlA9FMS7HsaWWhHy1YMB9BAaZ8uD0s8LXH4C&RelayState=9UITFKRCV-uUX7vdyNF6xIEybOVX2uDNZVohLi5OenU.q8U2Lp-_Lg8.http%3A%2F%2Flocalhost%3A8081%2Fpython-app
This is the request before encoding
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://localhost:8081/cgi-bin/saml-consumer.py"
Destination="http://localhost:8080/realms/SAML-Demp-Py/protocol/saml"
ID="1234"
IssueInstant="2021-09-17T18:41:20.295Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8081/python-app
</saml2:Issuer>
</saml2p:AuthnRequest>
Now once past this in the url I don't see the keycloak login screen. Instead the url in the browser is still the same as above and I see this json in the body of the page
{"realm":"SAML-Demp-Py","public_key":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvvoRDqFxcnJAmISv4qequAJ4w1dubE47Z2RStqVQ7oUZaUPO2magxvfa8CyaEwHuySkn42NjrafVMhZp/0gBVtsVW4uwNJCMXjvv8Tfbd4qUtVo50mEgGIpJRsm5RPXUJX2q1Yz/jX+U2vTfutEIDpRZGF6PtHt/tavuGt+qohpRycTWFvcEU7LuVu7Sj7AaOBNpgGSITUEYc09+JwrWcbenhrBZq9mJ5hgCw/0TU+HcwCIi1XgUVrzZ6OG0DwE702ezuDP2Nbs78U0w6tHUj+B1+p/TAntIg39CiwHHL3kIcwwJpHiJmeLNTlwlQm+Ny3w9LmP09dPAjMm2lw1qywIDAQAB","token-service":"http://localhost:8080/realms/SAML-Demp-Py/protocol/openid-connect","account-service":"http://localhost:8080/realms/SAML-Demp-Py/account","tokens-not-before":0}
You are using wrong endpoint. It is:
http://localhost:8080/realms/SAML-Demp-Py/protocol/saml?SAMLRequest=<encoded-saml-request>
instead of:
http://localhost:8080/realms/SAML-Demp-Py?SAMLRequest=<encoded-saml-request>

Cannot set `bearerOnly: true` in Keycloak 19.0

I am trying to secure my backend service but due to the updates with Keycloak 19.0 I can't follow any tutorial online. I am trying to set bearerOnly: true but there are no options to set the access type in new version of Keycloak
I tested v19.0.1, I can't find to option for bearerOnly option UI either but client JSON import after export and change bearerOnly true works.
I tested to import v18.0.2's JSON makes error.(attached image at the bottom)
So if you migrate from old version to 19.0.1 should be update manually base on v19's export JSON file.
Steps
Export Client JSON from v19
Delete #1 client
Switch "bearerOnly": true
Import #3 JSON in v19
This is bearerOnly true and false difference screen in UI
bearerOnly True option
bearerOnly False option
Using this JSON for True option
{
"clientId": "my-client-bearer-true",
"name": "My Client Bearer Only True",
"description": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": true,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "openid-connect",
"attributes": {
"oidc.ciba.grant.enabled": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.session.required": "true",
"backchannel.logout.revoke.offline.tokens": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"acr",
"roles",
"profile",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
If import v18.0.2 JSON file with bearerOnly true into v19.0.1,
It makes error
I using this V18 JSON file but It makes error as upper image.
So you can't import directly v18 JSON into V19.
{
"realm": "test",
"bearer-only": true,
"auth-server-url": "http://localhost:8180/auth/",
"ssl-required": "external",
"resource": "my-client",
"confidential-port": 0
}

Keycloak: roles not assigned when user is created via CLI

Running the below commands to import user with roles.
./kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password [pass]
./kcadm.sh create users -r [realm_name] -f user-admin.json
user-admin.json looks like:
{
"username": "adminLocal",
"enabled": true,
"totp": false,
"emailVerified": false,
"firstName": "admin",
"lastName": "local",
"email": "adminLocal#domain.com",
"disableableCredentialTypes": ["password"],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
},
"credentials" : [
{
"value" : "secret",
"type" : "password",
"temporary" : false
}
],
"realmRoles" : ["admin","offline_access","uma_authorization"]
}
Expected all the specified roles in "realmRoles" key to be assigned. However just Realm Default Roles: "offline_access","uma_authorization" were assigned to user.
The roles exist and were added beforehand via Keycloak Admin UI.
It's possible to create user and then assign roles as a workaround. However would like to do it with one command.

Setting up keycloak bearer-only client with https keycloak server

I have been trying to setup keycloak bearer-only client.Followed the steps mentioned in the keycloak documentation for javascript adapter. http works fine. With https, I was getting "Access Denied".
Below is the keycloak.json used in the client.
{
"realm": "MyRealm",
"auth-server-url": "https://10.65.107.118:8043/auth",
"ssl-required": "none",
"resource": "edge",
"bearer-only": true,
"public-client": true,
"use-resource-role-mappings": true,
"confidential-port": 0
}
The solution is to add "realm-public-key" in the keycloak.json.
The value of realm-public-key can be found from keycloak server. That is going to realm settings , one can find the public-key and copy-paste it in keycloak.json,to be used by client apps of this realm.
{
"realm": "MyRealm",
"auth-server-url": "https://10.65.107.118:8043/auth",
"ssl-required": "none",
"resource": "edge",
"bearer-only": true,
"public-client": true,
"use-resource-role-mappings": true,
"confidential-port": 0,
"realm-public-key": "MIIBIjANBgkqh..."
}
hope this helps somebody!

TFS 2015 Rest API - Create Build Definition

I'm trying to create a build definition in TFS using his api rest for it.
This is the microsoft docs for TFS Api Rest
I get status code 200 but...
This is what i get when I look into Tfs build definition
Anyone knows why this is happening?
Your second link provided a screenshot that a build definition with no tasks. It seems you had created a build definition successfully, but you didn't add tasks in the build definition.
Check your rest api to see whether you have "build": [] parameter with "task" in it as the following example shows:
"build": [
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Build solution **\\*.sln",
"task": {
"id": "71a9a2d3-a98a-4caa-96ab-affca411ecda",
"versionSpec": "*"
},
"inputs": {
"solution": "**\\*.sln",
"msbuildArgs": "",
"platform": "$(platform)",
"configuration": "$(config)",
"clean": "false",
"restoreNugetPackages": "true",
"vsLocationMethod": "version",
"vsVersion": "latest",
"vsLocation": "",
"msbuildLocationMethod": "version",
"msbuildVersion": "latest",
"msbuildArchitecture": "x86",
"msbuildLocation": "",
"logProjectEvents": "true"
}
},
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Test Assemblies **\\*test*.dll;-:**\\obj\\**",
"task": {
"id": "ef087383-ee5e-42c7-9a53-ab56c98420f9",
"versionSpec": "*"
},
"inputs": {
"testAssembly": "**\\*test*.dll;-:**\\obj\\**",
"testFiltercriteria": "",
"runSettingsFile": "",
"codeCoverageEnabled": "true",
"otherConsoleOptions": "",
"vsTestVersion": "14.0",
"pathtoCustomTestAdapters": ""
}
}
],