first login flow with SAML external IdP
by Manuel Waltschek
Hello there,
I have the use case that I want SP initiated SAML SSO against an external IdP. After succesful login on the external IdP I get redirected to my brokering IdP which wants to do some Authentication flow stuff, but I would like to skip authentication against keycloak and just redirect to my application after the assertion was successfully verified. After some research I found that this might not be implemented yet:
http://lists.jboss.org/pipermail/keycloak-user/2017-February/009605.html
https://issues.jboss.org/browse/KEYCLOAK-4240
So alternatively I thought of just importing a new user by following the steps of :
https://www.keycloak.org/docs/latest/server_admin/index.html#automaticall...
But what happens is, that I see two requests on http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/login-actions/... first one as GET with code 302 and after that the browser sends a POST to http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/after-f...
As POST-param it got the following EncryptedAssertion from my idp-broker:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="ID_38969c7e-58a0-4bd8-9699-2e4ee913f0fc" InResponseTo="ID_cdd51254-befe-4c11-a290-e8dc8fa3a769" IssueInstant="2018-12-11T15:44:49.960Z" Version="2.0"><saml:Issuer>http://localhost:8180/auth/realms/prisma-keycloak-saml-idp</saml:Issuer><dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><dsig:Reference URI="#ID_38969c7e-58a0-4bd8-9699-2e4ee913f0fc"><dsig:Transforms><dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><dsig:DigestValue>JvFxhVjCdc85MCr2WZJN285h4zKGevcFN/8oSgGBk/k=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>ahd0C3jr3gSCaHR2UDqNbzr5lVPL+2Dd2IggVhUZSuTRq9BEQXxOwe3jLK/7CldG39rSPkpxkyTMvGRMhJT5fe0sWf9U3PcsbT0h1vGUqphIaFb8Y0TizYpkeTrN2jk+d6+h3WrVYiOXg8PNyww0Vf7ParqIdKMkrAsQ4NVAlW9FWHgleN3N7EpZtrFiwPo7YyEc+8i95TtNA063+9rfS7J35HmOem+UjZXPKWSsWSc/JqqKo9KTLydGEVn6Nt4/lTophMB9YOP0kV0h/IkHwO0/fCCvn8SAObIDHo9sTQt6uQOOp9RnYIxT0Q0FW8L9MSl7uAhgb1jK06njKrfelA==</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIICvzCCAacCBgFnUHFoLDANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhwcmlzbWEta2V5Y2xvYWstc2FtbC1pZHAwHhcNMTgxMTI2MTQzMjQ4WhcNMjgxMTI2MTQzNDI4WjAjMSEwHwYDVQQDDBhwcmlzbWEta2V5Y2xvYWstc2FtbC1pZHAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC069gg6qpIEn61cp+kfqDnsTb93529dNPwmbs4ukxhOIFW7Ic6SsabDvvlokaC/fNOHcfLV8KSyTYcd4E8ESw65dGaGtBUwr2Egmq8U/KVOLxcjQStze6TZU3TAnaoU7ZhYXzCipnLEHMDzLSVUYUNVzX2cfNHwipGJvw8ribB51vKByn/LhyrhDfHGwmlP6Fkth3T0cKlN27x4s5zfBje1lp0uQagatUPcmwm51K3vSNHu1rz6CGOJviHVXu9T1T6adxw83Az6FK6Z+hNA/uzCYUafcY2xYK6z7nJiXVwbCg+ZYqRuWa/hjMZ3ViWb9J3iPGmjGfYQsYK5W/kyqiXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAwfSPO+MY8JTaI5qRF11O3iiMh99wTy+V9NdYp1No2HRxfAZiZeGTgWusYgrO2bQ37BGVs6Iw/7XU/eSzOfeYVmWgm1XFvimVq9Z8FVKfH93CRnhbmgnPV2wKPIlmKjzV5KinjZfbuX/6hO3jCRaYk4B4RgNnnNX5yJEbhxQdtRsTpYyPbxrLcCRx37T/U+g+JuoW03H23rFssS4OcEgoMPSBfKDE/DJDypOyl75YB8C0t5zOidFN0LNbw428X2LG04ZcD9rvyND9u5SEVzAjWp2EM7QD6klhXPDIyGSEMjKSNC+IFMpAmZLsHAVih8o8NqsNMxmsuEXVVONI1M0EY=</dsig:X509Certificate></dsig:X509Data><dsig:KeyValue><dsig:RSAKeyValue><dsig:Modulus>tOvYIOqqSBJ+tXKfpH6g57E2/d+dvXTT8Jm7OLpMYTiBVuyHOkrGmw775aJGgv3zTh3Hy1fCksk2HHeBPBEsOuXRmhrQVMK9hIJqvFPylTi8XI0Erc3uk2VN0wJ2qFO2YWF8woqZyxBzA8y0lVGFDVc19nHzR8IqRib8PK4mwedbygcp/y4cq4Q3xxsJpT+hZLYd09HCpTdu8eLOc3wY3tZadLkGoGrVD3JsJudSt70jR7ta8+ghjib4h1V7vU9U+mnccPNwM+hSumfoTQP7swmFGn3GNsWCus+5yYl1cGwoPmWKkblmv4YzGd1Ylm/Sd4jxpoxn2ELGCuVv5Mqolw==</dsig:Modulus><dsig:Exponent>AQAB</dsig:Exponent></dsig:RSAKeyValue></dsig:KeyValue></dsig:KeyInfo></dsig:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:EncryptedAssertion><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/><xenc:CipherData><xenc:CipherValue>WBkcmRAsyrpLfkrhnDWX1OwEW80bK5ICUjsHIVfyCsk9PSnSvDdhJyh7ZMgOv6/mAOL3jSEKDoJn2evbLkJR7g3UXzZ5RdS84vj+IgkynoxQtWpfWsIeziwkBUPSpxlviVUEI+/d/LouLlCBbhHF7JLkX4284NVN/TPOS7y6FwgA2lLmWGYefvce0W3DxN+g1NZDKlIo1GZlMrU4TwwkSP9zyedS+wdG1k3GssWa7g2PqRLWQcW59V6shI5FDltvFZDSINQurAQkQPQeLm+ibrRT78Nmp1X9x19G3DQ1PlsO6O/m05n/Uj8qX3EhJA8RP1TXQ/yQrNKzwbc2IGi7zQ==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>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</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml:EncryptedAssertion></samlp:Response>
As a response I get 405 Method not allowed and get redirected to a keycloak page saying "internal server error"
Why is this happening? Are there any good alternatives to this flow for my use case?
Thank you,
Manuel
6 years
Problem accessing admin console in 4.7 keycloak
by Tero Ahonen
Hi,
Just updated from 3.4 to 4.7, executed migration script without errors etc.
I’m running keycloak in container in Openshift and getting invalid
parameter redirect_uri when trying to login to console.
There is no error in the log when keycloak starts. Same config is working
for 3.4
master realms security-admin-console valid redirect url
is /auth/admin/master/console/*
Log says
11:50:09,795 WARN [org.keycloak.events] (default task-7) type=LOGIN_ERROR,
realmId=master, clientId=security-admin-console, userId=null,
ipAddress=10.131.10.1, error=invalid_redirect_uri, redirect_uri=
https://foobar.com/auth/admin/master/console/
Do I have to add valid hostname / domain to somewhere in the keycloak conf
or wildfly conf.
.t
6 years
How to create a 'provisioning only' user in Keycloak?
by Thomas Darimont
Hello Keycloak-Users,
I'd like to create users solely for Keycloak instance provisioning
operations (e.g. via kcadm.sh), which should not able to login via the
admin-console.
Does anyone know a way to do this?
Cheers,
Thomas
6 years
Re: [keycloak-user] UserStorageProvider for an external database
by Bart Lievens
Hello,
I solved the problem not by adding a datasource to WildFly but by adding the configuration parameters to the UserStorageProviderFactory
and creating the EntityManager inside the UserStorageProviderFactory and then passing it on when creating a UserStorageProvider.
My UserStorageProviderFactory looks something like (with 4.6.0.Final & 4.7.0.Final) :
public class ExternalUserStorageProviderFactory implements UserStorageProviderFactory<ExternalUserStorageProvider> {
private static final transient Logger logger = LoggerFactory.getLogger(ExternalUserStorageProviderFactory.class);
private static final String CONF_NAME_JDBC_URL = "jdbcUrl";
private static final String CONF_NAME_JDBC_USER = "user";
private static final String CONF_NAME_JDBC_PASSWORD = "password";
protected static final List<ProviderConfigProperty> configMetadata;
private Map<String, EntityManager> entityManagers = new HashMap<>();
static {
ProviderConfigurationBuilder builder = ProviderConfigurationBuilder.create();
builder.property().name(CONF_NAME_JDBC_URL).type(ProviderConfigProperty.STRING_TYPE).label("Jdbc Url")
.defaultValue("jdbc:postgresql://host:port/database")
.helpText("Postgres JDBC Connection URL to external user db")
.add();
builder.property().name(CONF_NAME_JDBC_USER).type(ProviderConfigProperty.STRING_TYPE).label("Jdbc User")
.helpText("JDBC Connection User")
.add();
builder.property().name(CONF_NAME_JDBC_PASSWORD).type(ProviderConfigProperty.PASSWORD).label("Jdbc Password")
.helpText("JDBC Connection Password")
.add();
configMetadata = builder.build();
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
return configMetadata;
}
@Override
public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel componentModel) throws ComponentValidationException {
if (componentModel.getConfig().getFirst(CONF_NAME_JDBC_URL) == null
|| componentModel.getConfig().getFirst(CONF_NAME_JDBC_USER) == null
|| componentModel.getConfig().getFirst(CONF_NAME_JDBC_PASSWORD) == null) {
throw new ComponentValidationException("The jdbc Url, User and Password are requirec");
}
try {
createEntityManager(componentModel);
} catch (Exception e) {
logger.warn("Invalid configuration {}", e.getCause() == null ? e.getMessage() : e.getCause().getMessage());
throw new ComponentValidationException("Could not setup jdbc connection : " + (e.getCause() == null ? e.getMessage() : e.getCause().getMessage()));
}
}
@Override
public ExternalUserStorageProvider create(KeycloakSession session, ComponentModel model) {
try {
if (entityManagers.get(model.getId()) == null) {
createEntityManager(model);
}
return new ExternalUserStorageProvider(entityManagers.get(model.getId()), model, session);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String getId() {
return "external-user-db";
}
@Override
public String getHelpText() {
return "External User Database Storage Provider";
}
private void createEntityManager(ComponentModel model) {
logger.info("creating entityManager for {}", model.getName());
Properties properties = getProperties(model);
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("external-user-storage", properties);
entityManagers.put(model.getId(), entityManagerFactory.createEntityManager());
}
private Properties getProperties(ComponentModel model) {
Properties properties = new Properties();
// Add class loader needed to find persistence.xml
properties.put(AvailableSettings.CLASSLOADERS, Arrays.asList(this.getClass().getClassLoader()));
// Set JPA properties
properties.put(AvailableSettings.JPA_PERSISTENCE_PROVIDER, HibernatePersistenceProvider.class.getName());
properties.put(AvailableSettings.JPA_TRANSACTION_TYPE, PersistenceUnitTransactionType.JTA.name());
// postgresql jdbc connection config
properties.put(AvailableSettings.JPA_JDBC_DRIVER, "org.postgresql.Driver");
properties.put(AvailableSettings.JPA_JDBC_URL, EnvUtil.replace(model.getConfig().getFirst(CONF_NAME_JDBC_URL)));
properties.put(AvailableSettings.JPA_JDBC_USER, EnvUtil.replace(model.getConfig().getFirst(CONF_NAME_JDBC_USER)));
properties.put(AvailableSettings.JPA_JDBC_PASSWORD, EnvUtil.replace(model.getConfig().getFirst(CONF_NAME_JDBC_PASSWORD)));
// hibernate
properties.put(AvailableSettings.DIALECT, org.hibernate.dialect.PostgreSQL95Dialect.class.getName());
properties.put(AvailableSettings.SHOW_SQL, Boolean.FALSE);
// set JTA properties
properties.put(AvailableSettings.JTA_PLATFORM, JBossAppServerJtaPlatform.class.getName());
return properties;
}
}
6 years
HTTP status 400 from Tomcat after successful login
by Timo Kockert
Hello everyone,
I have configured a web application, that is running in Tomcat, to
authenticate users with Keycloak. Everything is running fine if I
deploy the app to my local Tomcat, even when using the remote Keycloak
instance.
However, when I deploy the app to another Tomcat running behind an
Apache HTTP Server, the following happens:
* When I navigate to https://my-domain.tld/app I get redirected to the
Keycloak login
* After I log in successfully, Keycloak redirects me to
<IP>:<PORT>/app of the Tomcat
* The Tomcat answers with HTTP status 400
My keycloak.json looks like this:
{
"realm": "cdb_test",
"auth-server-url": "https://keycloak-server.tld/auth",
"ssl-required": "external",
"resource": "cdb_test",
"public-client": true
}
The VHost is configured like this:
ProxyPass /app http://<IP>:<PORT>/app/
ProxyPassReverse /app http://<IP>:<PORT>/app/
ProxyPassReverseCookiePath / /app/
I turned on debug logging for the Keycloak Tomcat adapter, see attachment.
Any advice?
Thanks in advance
Timo
6 years
Wrong AssertionConsumerServiceURL in AuthnRequest of IdP broker
by Manuel Waltschek
Hello there,
I am trying to configure my Keycloak server to act as an IdP broker for samltest.id IdP (external IdP) and I want my application to authenticate against this external IdP.
I imported the IdP Metadata of samltest into my IdP settings and exported following SP descriptor into IdP of samltest:
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://localhost:8180/auth/realms/prisma-keycloak-saml-idp">
<SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol http://schemas.xmlsoap.org/ws/2003/07/secext">
<KeyDescriptor use="signing">
<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<dsig:KeyName>Ovdow5dx1a_BxPju-WIV7_-LKmhBPUDGXMKEPsXoDYY</dsig:KeyName>
<dsig:X509Data>
<dsig:X509Certificate>MIICvzCCAacCBgFnUHFoLDANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhwcmlzbWEta2V5Y2xvYWstc2FtbC1pZHAwHhcNMTgxMTI2MTQzMjQ4WhcNMjgxMTI2MTQzNDI4WjAjMSEwHwYDVQQDDBhwcmlzbWEta2V5Y2xvYWstc2FtbC1pZHAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC069gg6qpIEn61cp+kfqDnsTb93529dNPwmbs4ukxhOIFW7Ic6SsabDvvlokaC/fNOHcfLV8KSyTYcd4E8ESw65dGaGtBUwr2Egmq8U/KVOLxcjQStze6TZU3TAnaoU7ZhYXzCipnLEHMDzLSVUYUNVzX2cfNHwipGJvw8ribB51vKByn/LhyrhDfHGwmlP6Fkth3T0cKlN27x4s5zfBje1lp0uQagatUPcmwm51K3vSNHu1rz6CGOJviHVXu9T1T6adxw83Az6FK6Z+hNA/uzCYUafcY2xYK6z7nJiXVwbCg+ZYqRuWa/hjMZ3ViWb9J3iPGmjGfYQsYK5W/kyqiXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAwfSPO+MY8JTaI5qRF11O3iiMh99wTy+V9NdYp1No2HRxfAZiZeGTgWusYgrO2bQ37BGVs6Iw/7XU/eSzOfeYVmWgm1XFvimVq9Z8FVKfH93CRnhbmgnPV2wKPIlmKjzV5KinjZfbuX/6hO3jCRaYk4B4RgNnnNX5yJEbhxQdtRsTpYyPbxrLcCRx37T/U+g+JuoW03H23rFssS4OcEgoMPSBfKDE/DJDypOyl75YB8C0t5zOidFN0LNbw428X2LG04ZcD9rvyND9u5SEVzAjWp2EM7QD6klhXPDIyGSEMjKSNC+IFMpAmZLsHAVih8o8NqsNMxmsuEXVVONI1M0EY=</dsig:X509Certificate>
</dsig:X509Data>
</dsig:KeyInfo>
</KeyDescriptor>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/prisma-..."/>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
</NameIDFormat>
<AssertionConsumerService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/prisma-..."
index="1" isDefault="true" />
</SPSSODescriptor>
</EntityDescriptor>
While "vde-tirol" is the client-id configured in my client and the ACS-url is the one I configured Fine Grain SAML Endpoint Configuration of my client.
After I try to access a protected ressource I get redirected to a page of samltest telling me there went something wrong and I detected that the authnrequest sent from my IdP broker did not have the ACS-url http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/prisma-...
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/prisma-..." Destination="https://samltest.id/idp/profile/SAML2/POST/SSO" ForceAuthn="false" ID="ID_86bcd6f8-2a66-4151-bfa1-35ad5cf5550b" IsPassive="false" IssueInstant="2018-12-07T16:08:26.742Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8180/auth/realms/prisma-keycloak-saml-idp</saml:Issuer>
<samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
</samlp:AuthnRequest>
I get the following Error from openSAML:
Endpoint Resolver org.opensaml.saml.common.binding.impl.DefaultEndpointResolver: Neither candidate endpoint location 'localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/prisma-keycloak-saml-idp/endpoint/clients/vde-tirol' nor response location 'null' matched 'http://localhost:8180/auth/realms/prisma-keycloak-saml-idp/broker/prisma-...'
Do you have a clue what went wrong? Is this intended behaviour, that the AssertionConsumerServiceURL in the AuthnRequest does not match?
Thank you in advance,
Manuel Waltschek
6 years
Gatekeeper security proxy configuration
by Scherer, Jonas
Hey everybody,
I try to replace the "old" keycloak security proxy (https://www.keycloak.org/docs/3.3/server_installation/topics/proxy.html)
with Gatekeeper (https://github.com/keycloak/keycloak-gatekeeper).
My setup is within Kubernetes and looks like:
Keycloak
|
|
Gatekeeper ---- reverse-proxy (Traefik) -- application
So http://mypage/myapplication arrives at port 80 on Gatekeeper (GK).
GK will check if the user is logged in and has the correct role and then will proxy the url to the service of my reverse-proxy,
which will handle the routing to the corresponding application within the Kubernetes-cluster.
Everything behind GK is just accessible inside the cluster.
This is working with the old setup and Keylcoak security-proxy, but with Gatekeeper everything is working as expected,
except the proxying to the reverse proxy.
It seems to redirect me to the kubernetes-service url instead of proxying the traffic through GK.
The reverse-proxy service is just accessible within the Cluster so this will not work for me.
Is there a way to configure Gatekeeper to work just like the security proxy?
Thank you for your help!
Jonas
6 years
Single Sign out in Spring MVC App
by Keshav Sharma
Hi ,
I want to logout from application but when I am doing logout form one app and again using the login url it is redirecting me to success page without doing authentication.
Please provide the configuration that needs to be done in spring mvc app so that I can configure logout correctly.
Regards,
Regards,
______________________________________________________
Keshav Sharma
Software Engineer
Direct: +91-124-479-6219
SHL | www.shl.com<http://www.shl.com/>
9th Floor, Tower 10-B, DLF Cyber City, Phase II,
Gurugram, Haryana - 122002, India
______________________________________________________
________________________________
This e-mail and/or its attachments are intended only for the use of the addressee(s) and may contain confidential and legally privileged information belonging to SHL and/or its affiliates. If you have received this e-mail in error, please notify the sender and immediately destroy all copies of this email and its attachments. The publication, copying, in whole or in part, or use or dissemination in any other way of this e-mail and attachments by anyone other than the intended person(s), is prohibited. If you would like to know how SHL collects, processes, uses, and stores personal data please go to www.shl.com/privacy to learn more.
6 years
Keycloak Modules developed for the Cloudtrust project
by Doswald Alistair
Hello,
I just wanted to let this mailing list know that for the Cloudtrust project (https://github.com/cloudtrust), we have developed a certain number modules for Keycloak. These are currently compatible with the version 3.4.3.Final of Keycloak, but we will make them compatible with Keycloak 4.X (where X will be the latest sub-version of Keycloak when we start working on this) as soon as we can. These modules are:
* keycloak-wsfed (https://github.com/cloudtrust/keycloak-wsfed): an implementation of the WS-Federation protocol for keycloak. This allows to select the WS-Federation protocol for Keycloak clients and for identity brokers.
* keycloak-authorization (https://github.com/cloudtrust/keycloak-authorization): this module allows the use of the client authorization system to prevent a user which is authenticated in a Keycloak realm to access a given client. It works no matter which protocol is used, and without the client having to support any extra protocol. Note: this solution is a bit hacky, but necessary for one of our use-cases.
* keycloak-client-mappers (https://github.com/cloudtrust/keycloak-client-mappers): a module for adding any mappers that we might need that are not yet part of Keycloak. Currently only contains a JavaScript mapper for SAML, analogous to the OIDC script mapper. I've noticed that there's an open issue for this feature (https://issues.jboss.org/browse/KEYCLOAK-5520). If desirable I could submit this code not as a module but a solution to the issue.
* keycloak-export (https://github.com/cloudtrust/keycloak-export): a module adding an endpoint to fully export a realm while Keycloak is still running (no need for restarts!).
Cheers,
Alistair
PS: I'm mailing this both dev and user mailing lists as I believe it may interest members of both mailing lists
6 years
get users from postman
by Luca Stancapiano
I'm trying to call via REST through POSTMAN the list of users through the get path: http://localhost:8180/auth/admin/realms/school-domain/users
Here my keycloak configuration where I create 2 users, 4 roles, a 'school' client and a 'school-domain' realm:
{
"realm": "school-domain",
"enabled": true,
"accessTokenLifespan": 60,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"ssoSessionIdleTimeout": 600,
"ssoSessionMaxLifespan": 36000,
"sslRequired": "external",
"registrationAllowed": true,
"resetPasswordAllowed": true,
"editUsernameAllowed": true,
"loginWithEmailAllowed": false,
"duplicateEmailsAllowed": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [
"password"
],
"users": [
{
"username": "root",
"enabled": true,
"email": "lsflashboss62(a)gmail.com",
"credentials": [
{
"type": "password",
"value": "gtn"
}
],
"realmRoles": [
"admin"
],
"clientRoles": {
"account": [
"manage-account"
]
}
},
{
"username": "HUHUJJJKJJKN",
"enabled": true,
"email": "luca.stancapiano(a)vige.it",
"firstName": "Luca",
"lastName": "Stancapiano",
"credentials": [
{
"type": "password",
"value": "gtn"
}
],
"realmRoles": [
"pupil"
],
"clientRoles": {
"account": [
"manage-account"
]
}
}
],
"clients": [
{
"clientId": "school",
"rootUrl": "http://localhost:8080/school",
"enabled": true,
"redirectUris": [
"http://localhost:8080/school/*"
],
"webOrigins": [
"http://localhost:8080"
],
"publicClient": false,
"secret": "bce5816d-98c4-404f-a18d-bcc5cb005c79",
"serviceAccountsEnabled": true,
"authorizationServicesEnabled": true,
"authorizationSettings": {
"allowRemoteResourceManagement": true,
"policyEnforcementMode": "ENFORCING",
"resources": [
{
"name": "Default Resource",
"type": "urn:school:resources:default",
"ownerManagedAccess": false,
"attributes": {
},
"_id": "c338b2be-da73-471c-9bb0-77ad52e1f88f",
"uris": [
"/*"
]
}
],
"policies": [
{
"id": "edb01393-180e-4d95-afd3-92b3ac5a6d41",
"name": "Default Policy",
"description": "A policy that grants access only for users within this realm",
"type": "js",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"code": "// by default, grants any permission associated with this policy\n$evaluation.grant();\n"
}
},
{
"id": "1f5dce97-54e3-4dcf-92bd-a2a59120286f",
"name": "Default Permission",
"description": "A permission that applies to the default resource type",
"type": "resource",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {
"defaultResourceType": "urn:school:resources:default",
"applyPolicies": "[\"Default Policy\"]"
}
}
],
"scopes": []
}
}
],
"roles": {
"realm": [
{
"name": "admin",
"description": "Administrator privileges"
},
{
"name": "schooloperator",
"description": "School Operator privileges"
},
{
"name": "teacher",
"description": "Teacher privileges"
},
{
"name": "pupil",
"description": "Pupil privileges"
}
]
}
}
Keycloak starts on the 8180 port. I configured POSTMAN with OAuth 2.0. Here the Oauth configuration used to receive the token:
Token Name: Token Name
Grant Type: Authorization Code
Callback URL: http://localhost:8080/school
Auth URL: http://localhost:8180/auth/realms/school-domain/protocol/openid-connect/auth
Access Token URL: http://localhost:8180/auth/realms/school-domain/protocol/openid-connect/t...
Client ID: school
Client Secret: bce5816d-98c4-404f-a18d-bcc5cb005c79
Client Authentication: Send as Basic Auth header
The Callback URL is an active simple web app starting on the 8080 port. The token creation is ok but when I call the server with the created token I get a 401 Unauthorized error. What I miss?
6 years