Hi everyone,
we are developing an extension of alfresco content service using the maven archetype.
Now, we would like to use keycloak for identity and access management.
We follow this guide Deploying Alfresco DBP with Identity Service using Docker Compose .
Everything work fine for authentication. Issues come when we try to use users and groups from keycloak.
We learned that, at the moment, the only way to sync users (and groups) between keycloak and alfresco is by SAML Module, that is available only for enterprise customer and we are using the community edition.
We found another module alfresco-keycloak, but we were unable to integrate it.
I think that the mantainer of this module is @afaust .
To integrate alfresco-keycloak we define these dependencies in our alfresco acs pom
<dependency> <groupId>de.acosix.alfresco.utility</groupId> <artifactId>de.acosix.alfresco.utility.repo</artifactId> <version>1.3.0-SNAPSHOT</version> <classifier>installable</classifier> </dependency>
<dependency>
<groupId>de.acosix.alfresco.keycloak</groupId>
<artifactId>de.acosix.alfresco.keycloak.repo</artifactId>
<version>1.1.0-rc7-SNAPSHOT</version>
<classifier>installable</classifier>
</dependency>
The 1.3.0-SNAPSHOT and 1.1.0-rc7-SNAPSHOT is the latest deployed on https://oss.sonatype.org/content/repositories/snapshots
Cutted stacktrace
Error creating bean with name 'keycloakDeployment' Caused by: java.lang.IllegalArgumentException: You did not supply enough values to fill path parameters edi-acs_1 | at de.acosix.alfresco.keycloak.deps.keycloak.common.util.KeycloakUriBuilder.buildFromValues(KeycloakUriBuilder.java:577)
Configuration
authentication.chain=keycloak1:keycloak,alfrescoNtlm1:alfrescoNtlm keycloak.adapter.auth-server-url=${KEYCLOAK_URL} keycloak.adapter.credentials.provider=secret keycloak.adapter.realm=${KEYCLOAK_REALM} keycloak.adapter.resource=${KEYCLOAK_CLIENT} keycloak.adapter.credentials.secret=xxxxxxxx
${KEYCLOAK_URL} ${KEYCLOAK_REALM} ${KEYCLOAK_CLIENT} are set through -D options
Maybe he could help us...
Thanks
Solved! Go to Solution.
Thanks for mentioning me in your post, otherwise I might have missed it. In general, if you want the maintainer of a module to look into one of your issues, it is a good idea to raise such questions / issues in the issue tracker of the addon project - if the project has an issue tracker. Since the alfresco-keycloak addon is on GitHub, it has an issue tracker by default.
Your placeholders are not resolved because of a general limitation in how Alfresco resolves -D flags to configuration properties. In general, only configuration properties which have been pre-defined in a pre-packaged configuration file (repository.properties, module alfresco-global.properties, or subsystem instance type *.properties) can be resolved. That means in one of those files you would have to have an entry in the form of
KEYCLOAK_REALM=
for a -DKEYCLOAK_REALM=xyz property to be effective, and be referenceable via a ${KEYCLOAK_REALM} placeholder in other properties. The reason for this is that Alfresco only uses an override mode of handling -D flags instead of fully merging them.
For the ADF part, I must admit I do not test this as I do not use ADF / ACA / ADW at all in any projects (those are generally useless / too much effort to deal with to achieve even basic non-trivial solutions - compared to Share), so I can't immediately give you an educated guess of what might be failing - I also don't know anythign about your ADF / Keycloak realm config for handling OAuth. What I could imagine is that you are trying to use a Keycloak access token obtained for the ADF application (as a public client) to directly call ACS, which potentially fails in some validation step, assuming ACS is set up as its own Keycloak client. "Unfortunately", the alfresco-keycloak addon is set up to be more compliant / consistent / secure when interacting with Keycloak, while the Identity Service integration really uses a naiive fire/once-and-forget type of integration.
For alfresco-keycloak, it would normally be expected that a client calling ACS exchange their access token for an access token to the backend resource. As far as I can remember, ADF requires a public-client type of Keycloak client, which means it will be unable to do such an exchange. You may want to try
keycloak.adapter.verify-token-audience=false
to disable one of the validations, and allow an access token from a public client to be used for direct authentication without exchanging it.
Thanks for you reply @afaust .
I know that github has its own issue tracker, but I posted in alfresco forum because I think it could be usefull for other people that want to integrate your module with their own alfresco extension.
By the way, I will open an issue on github about the release of no SNAPSHOT version compliant to 7.0 :-)
Regarding the issue with ADF, I understand what you say about the flow of the token. I will try to set verify-token-audience to false.
At the moment, I try to use both identity-service and keycloak-alfresco in my configuration
authentication.chain=identity-service1:identity-service,keycloak1:keycloak,alfrescoNtlm1:alfrescoNtlm keycloak.authentication.enabled=false keycloak.authentication.sso.enabled=false keycloak.adapter.auth-server-url=https://xxxxx keycloak.adapter.realm=yyyyy keycloak.adapter.resource=zzzz keycloak.adapter.credentials.provider=secret keycloak.adapter.credentials.secret=1wwwww keycloak.adapter.ssl-required=external identity-service.authentication.enabled=true identity-service.enable-basic-auth=false identity-service.authentication.validation.failure.silent=false identity-service.auth-server-url=${KEYCLOAK_URL} identity-service.realm=${KEYCLOAK_REALM} identity-service.resource=${KEYCLOAK_CLIENT}
it seems to work.
Hi,
I reply myself. Using values instead placeholders in properties file, alfresco-keycloak starts successfully and users and groups were sinchronyzed.
I try to investigate why placeholders are not replaced. If I use identity service module everythings work.
Thanks.
-S.
Now we have another problem: we are using only ACS repository (no share). UI are developed using ADF.
With identity service API calls work.
With alfresco-keycloak, they return 500 with generic Alfresco error page.
This is our configuration
keycloak.authentication.enabled=true keycloak.authentication.sso.enabled=true keycloak.authentication.sso.handlePublicApi=true keycloak.adapter.auth-server-url=https://xxxxx/auth keycloak.adapter.realm=yyyyyyy keycloak.adapter.resource=zzzzz keycloak.adapter.credentials.provider=secret keycloak.adapter.credentials.secret=wwwwwwwww keycloak.adapter.autodetect-bearer-only=true keycloak.adapter.enable-basic-auth=true keycloak.adapter.ssl-required=external
Thanks for mentioning me in your post, otherwise I might have missed it. In general, if you want the maintainer of a module to look into one of your issues, it is a good idea to raise such questions / issues in the issue tracker of the addon project - if the project has an issue tracker. Since the alfresco-keycloak addon is on GitHub, it has an issue tracker by default.
Your placeholders are not resolved because of a general limitation in how Alfresco resolves -D flags to configuration properties. In general, only configuration properties which have been pre-defined in a pre-packaged configuration file (repository.properties, module alfresco-global.properties, or subsystem instance type *.properties) can be resolved. That means in one of those files you would have to have an entry in the form of
KEYCLOAK_REALM=
for a -DKEYCLOAK_REALM=xyz property to be effective, and be referenceable via a ${KEYCLOAK_REALM} placeholder in other properties. The reason for this is that Alfresco only uses an override mode of handling -D flags instead of fully merging them.
For the ADF part, I must admit I do not test this as I do not use ADF / ACA / ADW at all in any projects (those are generally useless / too much effort to deal with to achieve even basic non-trivial solutions - compared to Share), so I can't immediately give you an educated guess of what might be failing - I also don't know anythign about your ADF / Keycloak realm config for handling OAuth. What I could imagine is that you are trying to use a Keycloak access token obtained for the ADF application (as a public client) to directly call ACS, which potentially fails in some validation step, assuming ACS is set up as its own Keycloak client. "Unfortunately", the alfresco-keycloak addon is set up to be more compliant / consistent / secure when interacting with Keycloak, while the Identity Service integration really uses a naiive fire/once-and-forget type of integration.
For alfresco-keycloak, it would normally be expected that a client calling ACS exchange their access token for an access token to the backend resource. As far as I can remember, ADF requires a public-client type of Keycloak client, which means it will be unable to do such an exchange. You may want to try
keycloak.adapter.verify-token-audience=false
to disable one of the validations, and allow an access token from a public client to be used for direct authentication without exchanging it.
Thanks for you reply @afaust .
I know that github has its own issue tracker, but I posted in alfresco forum because I think it could be usefull for other people that want to integrate your module with their own alfresco extension.
By the way, I will open an issue on github about the release of no SNAPSHOT version compliant to 7.0 :-)
Regarding the issue with ADF, I understand what you say about the flow of the token. I will try to set verify-token-audience to false.
At the moment, I try to use both identity-service and keycloak-alfresco in my configuration
authentication.chain=identity-service1:identity-service,keycloak1:keycloak,alfrescoNtlm1:alfrescoNtlm keycloak.authentication.enabled=false keycloak.authentication.sso.enabled=false keycloak.adapter.auth-server-url=https://xxxxx keycloak.adapter.realm=yyyyy keycloak.adapter.resource=zzzz keycloak.adapter.credentials.provider=secret keycloak.adapter.credentials.secret=1wwwww keycloak.adapter.ssl-required=external identity-service.authentication.enabled=true identity-service.enable-basic-auth=false identity-service.authentication.validation.failure.silent=false identity-service.auth-server-url=${KEYCLOAK_URL} identity-service.realm=${KEYCLOAK_REALM} identity-service.resource=${KEYCLOAK_CLIENT}
it seems to work.
We try to set parameter as @afaust suggests to us and for basic operations works.
So, our new configuration is
authentication.chain=keycloak1:keycloak,alfrescoNtlm1:alfrescoNtlm keycloak.authentication.sso.handlePublicApi=true keycloak.authentication.enabled=true keycloak.authentication.sso.enabled=true keycloak.adapter.verify-token-audience=false keycloak.adapter.auth-server-url=https://xxx keycloak.adapter.realm=yyyy keycloak.adapter.resource=zzzz keycloak.adapter.credentials.provider=secret keycloak.adapter.credentials.secret=wwww keycloak.adapter.ssl-required=external keycloak.adapter.autodetect-bearer-only=true keycloak.adapter.enable-basic-auth=false
Now we have another problem regarding the Alfresco Repository client roles (ROLE_ADMINISTRATOR, ROLE_GUEST, GROUP_SITE_ADMINISTRATORS, ...) when we use ACS through APIs.
But it is another story...
Thanks.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.