Giter VIP home page Giter VIP logo

alfresco-keycloak's Introduction

Build Status

About

This addon aims to provide a Keycloak-related extensions / customisations to the out-of-the-box Alfresco authentication and authorisation functionalities for the Alfresco Repository and Share tiers.

Compatbility

This module is built to be compatible with Alfresco 6.0 and above. It may be used on either Community or Enterprise Edition.

Features

The Repository sub-module provides a custom authentication subsystem dealing with Keycloak (separate to Alfresco's default identity-service) and customisations which support:

  • user + password login via AuthenticationService.authenticate / AuthenticationComponent.authenticate
  • Bearer token authentication using a client-obtained access token
  • redirection to Keycloak login UI and OIDC authentication flow (SSO), if client not already authenticated in session, no pre-emptive details provided in request and API requires authentication
  • mapping of person properties on authentication from user access / identity token
  • mapping of authorities from user access token (for purpose of permission / role checks)
  • handling Keycloak back-channel requests
    • back-channel logout requests from Keycloak (i.e. SSO including "single sign-out")
    • bulk-invalidation of access tokens issued before a certain point in time
    • availability test / basic validation
    • JWKS (public key) update
  • active user / group synchronisation against Keycloak's directory (which may include users / groups synchronised from multiple federated directories)
  • Java service, JavaScript service and web script to expose roles mapped from Keycloak for retrieval (e.g. to be used in permission management)

The Share sub-module provides a Keycloak-based filter and customisations that support:

  • redirection to Keycloak login UI and OIDC authentication flow (SSO), if client not already authenticated in session, no pre-emptive details provided in request and SSO authentication required/enforced via configuration
  • enhancement of the login dialog to allow users to perform an alternative, external authentication via Keycloak
  • handling Keycloak back-channel requests
    • back-channel logout requests from Keycloak (i.e. SSO including "single sign-out")
    • bulk-invalidation of access tokens issued before a certain point in time
    • availability test / basic validation
    • JWKS (public key) update
  • Share logout action triggering a Keycloak logout (logging user out of other applications handled by Keycloak if those support Keycloak back-channel logout requests)
  • RFC 8693 OAuth 2.0 Token Exchange (a preview functionality in Keycloak to properly delegate the Share-tier authentication to the Repository, if signed on via Keycloak SSO

All authentication functionality of this addon is based on OpenID Connect. Though Keycloak does support SAML clients, no support was implemented to have Alfresco act as a SAML client against Keycloak as an alternative to OpenID Connect client behaviour.

Configuration

The configuration of both the Keycloak server and this module offer a large number of properties to adjust, and various modes of operation. Therefore, the following sub-documents have been created to provide details and guides:

Build

This project uses a Maven build using templates from the Acosix Alfresco Maven project and produces module AMPs, regular Java classes JARs, JavaDoc and source attachment JARs, as well as installable (Simple Alfresco Module) JAR artifacts for the Alfresco Content Services and Share extensions. If the installable JAR artifacts are used for installing this module, developers / users are advised to consult the 'Dependencies' section of this README.

Maven toolchains

By inheritance from the Acosix Alfresco Maven framework, this project uses the Maven Toolchains plugin to allow potential cross-compilation against different Java versions. This plugin is used to avoid potentially inconsistent compiler and library versions compared to when only the source/target compiler options of the Maven compiler plugin are set, which (as an example) has caused issues with some Alfresco releases in the past where Alfresco compiled for Java 7 using the Java 8 libraries. In order to build the project it is necessary to provide a basic toolchain configuration via the user specific Maven configuration home (usually ~/.m2/). That file (toolchains.xml) only needs to list the path to a compatible JDK for the Java version required by this project. The following is a sample file defining a Java 8 and 11 development kit.

<?xml version='1.0' encoding='UTF-8'?>
<toolchains xmlns="http://maven.apache.org/TOOLCHAINS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/TOOLCHAINS/1.1.0 http://maven.apache.org/xsd/toolchains-1.1.0.xsd">
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.8</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>C:\Program Files\Java\jdk1.8.0_231</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.11</version>
      <vendor>oracle</vendor>
      <id>openjdk11</id>
    </provides>
    <configuration>
      <jdkHome>C:\Program Files\Java\jdk-11.0.2</jdkHome>
    </configuration>
  </toolchain>
</toolchains>

The master branch requires Java 8.

Docker-based integration tests

In a default build using mvn clean install, this project will build the extension for Alfresco Content Services, executing regular unit-tests without running integration tests. The integration tests of this project are based on Docker and require a Docker engine to run the necessary components (PostgreSQL database as well as Alfresco Content Services). Since a Docker engine may not be available in all environments of interested community members / collaborators, the integration tests have been made optional. A full build, including integration tests, can be run by executing

mvn clean install -Ddocker.tests.enabled=true

This project currently does not yet contain any specific integration tests but does use integration tests to verify Alfresco correctly starts up with the addon installed.

Dependencies

This module depends on the following projects / libraries:

  • various Keycloak adapter and client libraries (Apache License, Version 2.0)
    • keycloak-adapter-core
    • keycloak-servlet-adapter-spi
    • keycloak-servlet-filter-adapter
    • keycloak-authz-client
  • JBoss Logging (Apache License, Version 2.0)
  • Acosix Alfresco Utility (Apache License, Version 2.0) - core extension

All Keycloak and JBoss dependencies are aggregated (shaded) directly into the module library for Repository and Share respectively. This has been done to isolate this addon from whatever version of Keycloak libraries Alfresco pre-packages to support its identity-service authentication subsystem.

The Acosix Alfresco Utility project provides the core extension for Alfresco Content Services as a separate artifact from the full module, which needs to be installed in Alfresco Content Services before the AMP of this project can be installed.

When the installable JAR produced by the build of this project is used for installation, the developer / user is responsible to either manually install all the required components / libraries provided by the listed projects, or use a build system to collect all relevant direct / transitive dependencies. Note: The Acosix Alfresco Utility project is also built using templates from the Acosix Alfresco Maven project, and as such produces similar artifacts. Automatic resolution and collection of (transitive) dependencies using Maven / Gradle will resolve the Java classes JAR as a dependency, and not the installable (Simple Alfresco Module) variant. It is recommended to exclude Acosix Alfresco Utility from transitive resolution and instead include it directly / explicitly.

Using SNAPSHOT builds

In order to use a pre-built SNAPSHOT artifact published to the Open Source Sonatype Repository Hosting site, the artifact repository may need to be added to the POM, global settings.xml or an artifact repository proxy server. The following is the XML snippet for inclusion in a POM file.

<repositories>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

alfresco-keycloak's People

Contributors

afaust avatar howkymike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alfresco-keycloak's Issues

[BUG] Skipping processKeycloakAuthenticationAndActions as login page was explicitly requested

Hello @AFaust

Bug description

I noticed that when I'm logged out and I access a shared page (i.e. https://example.com/share/s/ABCD) and click "Login":

  1. Forced SSO does not work (i have force-keycloak-sso enabled) - I'm redirected to standard Alfresco's login page
  2. After clicking "Sign via SSO" I'm redirected again to the login page over and over again

Proposed Solution:

In the KeycloakAuthenticationFilter.checkForSkipCondition() function there is a check if page is explicitly requesting a login page. If yes, whole Keycloak authentication is omitted. I propose to delete this check.

Additional note

I have a feeling that also other checks in this function might have to be deleted - there are other situations when this happens as well.

Newbie here

Hi,
My name is Matteo and I'm new at java programming, and I've to make possible the keycloak->Alfresco integration.
I found your project and now I'm trying to compile it correctly. Obviously I need the amp to add to Alfresco.
I'm also new in the use of maven.
I've correctly done "mvn clean install" to obtain the amp file, but when I try to apply it to Alfresco Community 6.2 the response is:

02190001 An error was encountered during deployment of the AMP into the WAR: 02190000 The following modules must first be installed: [acosix-utility:1.2.5-*]
Module 'acosix-keycloak' installed in '/appsrv/alfresco/6.2.0-ga/tomcat/webapps/alfresco.war'

  • Title: Acosix Alfresco Keycloak - Share Module
  • Version: 1.1.0-rc6

02190001 An error was encountered during deployment of the AMP into the WAR: 02190000 The following modules must first be installed: [acosix-utility:1.2.5-*]
Module 'acosix-keycloak' installed in '/appsrv/alfresco/6.2.0-ga/tomcat/webapps/share.war'

  • Title: Acosix Alfresco Keycloak - Share Module
  • Version: 1.1.0-rc6

now I've tried to add the acosix-utility into the keycloak project modifing the pom file how I've found on internet. But I cannot found it into the lib directory into the target amp file like bcprov-jdk15on-1.66.jar.
How can I do it working? I'm using IntellijIdea.
Thank you a lot!
Many greetings
Matteo

sso.originalRequestUrlHeaderName vurnerability?

Hi @AFaust ,

I see that the default value for sso.originalRequestUrlHeaderName is 'X-Original-Request-URL'
I think that the use of the X-Original-Request-URL header could expose a vulnerability. A user can inject a custom url in this header.
If used correctly it can be very useful, but that means that at some point a proxy should add this header should add or overwrite this header in every request.
I think that it might be a good idea to disable (or empty) this header in a default configuration.

Best regards.

Problems with token exchange

Hello @AFaust
Your addon looks really awesome, I successfully set up the Repository part (I can create a user in Keycloak and then sign in to Alfresco).
Unfortunately, I have a problem with the Share configuration. After clicking Login with SSO, I'm getting a "Something wrong with this page..." error. In the logs I can see:

SEVERE: Servlet.service() for servlet [Spring Surf Dispatcher Servlet] in context with path [/share] threw exception
org.alfresco.error.AlfrescoRuntimeException: 04180000 Failed to retrieve access token due to HTTP error 400: Bad Request
        at de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter.getAccessToken(KeycloakAuthenticationFilter.java:1738)
        at de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter.handleAlfrescoResourceAccessToken(KeycloakAuthenticationFilter.java:1628)
        at de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter.onKeycloakAuthenticationSuccess(KeycloakAuthenticationFilter.java:912)
        at de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter.processFilterAuthentication(KeycloakAuthenticationFilter.java:721)
        at de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter.processKeycloakAuthenticationAndActions(KeycloakAuthenticationFilter.java:615)
        at de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter.doFilter(KeycloakAuthenticationFilter.java:488)
        at org.springframework.extensions.webscripts.servlet.BeanProxyFilter.doFilter(BeanProxyFilter.java:80)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:81)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

2021-05-18 14:16:12,425  ERROR [alfresco.web.site] [http-nio-8080-exec-9] org.alfresco.error.AlfrescoRuntimeException: 04180000 Failed to retrieve access token due to HTTP error 400: Bad Request

My share configuration:

  • auth-server-url -> https://my.domain.com/auth (when I change it to http://localhost:8085, the form action URL i in the login page is also localhost, so it is unavailable)
  • prefix of every endpoint-url is http://localhost:8080
    I attached full share-config-custom.xml and nginx.conf.
    configFiles.zip

Alfresco Repository, Share, Keyclock are running on a single machine (standalone/zip installation) on localhost/0.0.0.0. They are behind Nginx with Let's encrypt.

I also tried to following setup:

  • directAuthHost to localhost:8085 (keycloak is running on 8085, becasue Alfresco Repo is on 8080),
  • auth-server-url to https://my.domain.com/auth
  • ssl-required to external

But then, when I click "Sign with SSO", accept the "Form is not secure" message (Chrome browser), provide credentials in Keyclock and click "Log in", it redirects be again to Alfresco login page and in the logs I can see the following error:

2021-05-18 14:04:59,104 ERROR [de.acosix.alfresco.keycloak.deps.keycloak.adapters.OAuthRequestAuthenticator] [http-nio-8080-exec-42] failed verification of token: Invalid token issuer. Expected 'http://my.domain.com/auth/realms/alfresco', but was 'https://my.domain.com/auth/realms/alfresco' 2021-05-18 14:04:59,106 WARN [de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter] [http-nio-8080-exec-42] Keycloak authentication failed due to <missing AuthenticationError details in request context>

NewBie , Naive Question !

Hello,

i installed alfresco community by docker-compose
how can integrate with this addon to my current installation?
or how can I run this identity service?

Unable to init docker image alfresco-content-repository-community:7.0.0 using keycloak.repo-1.1.0-rc7-SNAPSHOT.amp (and rc6)

Hi,

I am experimenting with alfresco-keycloak using docker images (alfresco-content-repository-community:7.0.0), but, as soon as I installed the amps (and theirs dependencies), alfresco-repo is not able to start.

I got the following logs

03-Jun-2021 03:07:20.969 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.alfresco.web.app.ContextLoaderListener]
        org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'transformer.acosix-utility.Rfc822ToHtml' defined in file [/usr/local/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/module/acosix-utility/module-context.xml]: Could not resolve parent bean definition 'baseContentTransformer'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'baseContentTransformer' available
                at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1417)
                at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1358)
                at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1344)

alfresco-share starts (I get the login screen), but I am unable to login because content services (repo) is not available.

I have both alfresco-global.properties and share-config-custom.xml set.

BTW, I faced the same issue using pre-packaged rc6 amps.

Any debugging suggestion?

Thanks in advance!

build error

tried building:

mvn clean install

getting error:

[ERROR] Failed to execute goal de.acosix.maven:jshint-plugin:1.1.0:jshint (Validate Webapp) on project de.acosix.alfresco.keycloak.repo: Execution Validate Webapp of goal de.acosix.maven:jshint-plugin:1.1.0:jshint failed: Plugin de.acosix.maven:jshint-plugin:1.1.0 or one of its dependencies could not be resolved: Could not find artifact de.acosix.alfresco.maven:de.acosix.alfresco.maven.definitions:jar:1.3.4-SNAPSHOT in ossrh (https://oss.sonatype.org/content/repositories/snapshots) -> [Help 1]

is master not ready for building yet?

thanks,

max

Issues with https connection configuring

Hi @AFaust

I have a dockerized Alfresco Community (version 6.2.0-ea) and Share (version 6.2.0) are under Nginx. SSL is set up in Nginx. Keycloak (version 11.0.2) is configured separately, SSL is set up directly in it.
We need an https connection with a Keycloak remote server.

How it is working now:
I go to the Share Login Page, click the "Login via SSO" button and I am redirected to the login page of the Keycloak, I log in and I am redirected back to the Share Login Page (with the "Login via SSO" button). And I can't go anywhere else. In Keycloak, the user is being logged in, the user also appears in Alfresco, if I check through the Node Browser.

In logs, I found the next lines:

ERROR [keycloak.adapters.OAuthRequestAuthenticator] [http-nio-8080-exec-2] failed to turn code into token
ERROR [keycloak.adapters.OAuthRequestAuthenticator] [http-nio-8080-exec-2] status from server: 400
ERROR [keycloak.adapters.OAuthRequestAuthenticator] [http-nio-8080-exec-2]    {"error":"invalid_grant","error_description":"Incorrect redirect_uri"}
WARN  [share.web.KeycloakAuthenticationFilter] [http-nio-8080-exec-2] Keycloak authentication failed due to <missing AuthenticationError details in request context>

What are we doing wrong? Is there a solution to this problem? The configuration files are attached in the "attachments.zip" archive.
attachments.zip

Another nuance is the directAuthHost property - why can't I specify something other than "http://keyloak_host:8080"? In all other cases (when I change the "http" scheme to "https" one or when I change the port 8080 to another some), the logs write warn message:

Cannot process Keycloak-specifics as Keycloak library was unable to resolve relative URLs from ...

and Alfresco redirects to the default Share login page. Although on the Keycloak side, only ports 80 and 443 are opened for http and https respectively.

Thanks in advance.

Hi Alex, can you support us for Alfresco Keycloak Integration?

Hi Alex,

We have configured a docker-compose based installation of alfresco community (https://github.com/Alfresco/acs-community-deployment/blob/master/docker-compose/docker-compose.yml) and I am trying to setup your add-on with keycloack 12.0.4, standalone.

I have cloned and build alfresco-utility and alfresco-keycloak, both the amp files.
The docker-compose starts successfully.
In alfresco repository i find two amps:

  • de.acosix.alfresco.keycloak.repo-1.1.0-rc6.amp
  • de.acosix.alfresco.utility.repo-1.2.5.amp
    In alfresco share i find the two other amps:
  • de.acosix.alfresco.keycloak.share-1.1.0-rc6.amp
  • de.acosix.alfresco.utility.share-1.2.5.amp

When i go to the console i can see the amps for share
image

First time i set the base url of KC with this value "http://localhost:8180/auth" and Share starts with a warning. It cannot resolve "localhost:8180".
So I set the base url of keycloak with this value: "http://host.docker.internal:8180/auth". All the docker-compose starts successfully, and if i go in the share container i am able to download the index page of keycloak with a "wget http://host.docker.internal:8180/auth".

So I think that all the containers are started very good and that i haven't network issues.

But if I go to http://localhost:8080/share i see the default login page of Share, with no SSO button.

Am I doing something wrong with the installation?

Regarding the configuration of alfresco-global.properties and share-config-custom.xml: i am not sure to understand correctly the documentation. All the values about sso are managed by these two files in the repo?

  • src/main/globalConfig/subsystems/Authentication/keycloak/keylocak-authentication.properties
  • src/main/config/default-config.xml

Or maybe i have to move and edit these file in another position?

thank you in advance

questions

hi,

i've just seen this alfresco keycloak extension, and having a few questions:

  • this extension also supports alfresco community share, which official alfresco keycloak (identity services) doesn't?
  • is it possible to use a "real" keycloak server version instead of the alfresco implementation (identity services)

what would be the necessary steps to test these extensions e.g. for using/testing with alfresco share:

  • install and configure keycloak or alfresco identity services?
  • build and install Acosix Alfresco Utility project amp?
  • build and install repo and share amps from this repo?
  • configuration: what needs to be configured? alfresco-global.properties? share-custom.config?
  • other steps?

Thanks for any insights to my questions,
cheers,
Max

Unable to retrieve user from repository (token-exchange turned off)

Probably related to #12

First, I would like to thank you for this awesome addon!

I am experimenting with alfresco-keycloak using docker images (alfresco-content-repository-community:6.2.1-A8) and I managed to use keycloak as an authentication backend.

I made my best effort to follow the alfresco-keycloak documentation, by configuring a realm and different clients for Repo (repo-client) and Share (share-client). (I believe) I didn't miss any step when configuring Repo and Share to allow for alfresco-keycloak extended services.

In a first approach, I decided to turn off token exchange after setting verify-token-audience and perform-token-exchange to false. In this scenario, I didn't configure a authorization policy in realm-management client.

I managed to log in to Repo resources (http://localhost:8080/alfresco/wcs/admin) using keycloak repo-client and I was able to login to Share (http://localhost:8080/share), but, as soon as keycloak share-client checks the user's credentials, I can't get to the user's dashboard. I get the following page.

Captura de tela de 2021-06-08 23-44-27

Share log reports Unable to retrieve user from repository

share_1               | 2021-06-09 02:37:29,207  ERROR [alfresco.web.site] [http-nio-8080-exec-5] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
share_1               |  org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
share_1               | 	at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:195)
share_1               | 	at org.alfresco.web.site.SlingshotUserFactory.loadUser(SlingshotUserFactory.java:146)
share_1               | 	at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:183)
share_1               | 	at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:101)
share_1               | 	at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:260)
share_1               | 	at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:183)
share_1               | 	at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:138)
share_1               | 	at de.acosix.alfresco.keycloak.share.web.PopulatingRequestContextInterceptor.preHandle(PopulatingRequestContextInterceptor.java:57)
....
share_1               | Caused by: org.springframework.extensions.surf.exception.UserFactoryException: Unable to create user - failed to retrieve user metadata: 
share_1               | 	at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:185)
share_1               | 	... 49 more
...

Any debugging suggestion?

Thanks in advance!

Repository IdP authentication

Hi Axel,

I have installed your modules in the Repo and work great.
Role mapping, User sync and authentication with a Keycloak User that is authenticated with Keycloak itself.
But using the IdP or LDAP password isn't possible.

In our situation I need this for Authenticating against a SAML IdP with MFA.

I thought and hoped this would be possible, but I keep on getting the old login box and are not referred to the IdP.
If I get a token through the Share or App I can also successfully login to the Repository but that is not always the case.
We would like to setup AOS with Keycloak broker and IdP.

How can I configure this or is this not possible.

I followed the simple configuration documentation and configured the following in the JAVA_OPTS:
-Dauthentication.chain=alfrescoNtlm1:alfrescoNtlm,keycloak1:keycloak
-Dkeycloak.authentication.enabled=true
-Dkeycloak.authentication.sso.enabled=true
-Dkeycloak.authentication.handlePublicApi=false
-Dkeycloak.authentication.allowTicketLogons=true
-Dkeycloak.authentication.allowHttpBasicLogon=false
-Dkeycloak.authentication.allowUserNamePasswordLogin=true
-Dkeycloak.authentication.mapAuthorities=true
-Dkeycloak.authentication.mapPersonPropertiesOnLogin=true
-Dkeycloak.enable-basic-auth=true
-Dkeycloak.authentication.defaultAdministratorUserNames='admin'
-Dkeycloak.authentication.validation.failure.silent=false
-Dkeycloak.adapter.realm=alfresco
-Dkeycloak.adapter.resource=alfresco
-Dkeycloak.adapter.credentials.secret=f580d6c7-d465-403d-8209-6b061fad4d8a
-Dkeycloak.adapter.auth-server-url=https://my-alfresco-base-url/auth
-Dkeycloak.adapter.verify-token-audience=true
-Dkeycloak.synchronization.enabled=true

I hope you can point me in the right direction on this.

Regards,

Dick

Incompatible with 23.1.0

With Alfresco's abandonment of the Identity Service, this little project was the only thing I could get working with Keycloak on version 7.4.X .
With the advent of 23.1.0 and the transition from javax.XXX to jakarta.XXX, I was unable to compile the project.

I tried updating the Keycloak to version 23.X.X and modify the code a little , but without success.

Could you make the project compatable for Alfresco version 23.1.0 as well ? Ty in advance.

Help with configuration and debugging

Hi Axel,

I am trying to run this module with Alfresco 6.2. I am getting this warning message and can't find a way to get more details - as the url looks correct:
2023-01-13 09:18:19,569 WARN [de.acosix.alfresco.keycloak.repo.authentication.KeycloakAuthenticationFilter] [http-nio-8080-exec-2]
Cannot process Keycloak-specifics as Keycloak library was unable to resolve relative URLs from http://localhost:8880/auth

It is just a warning, but seems critical to me (to the functioning of this module). Is there a way to enable further debugging to understand what is going wrong? And would you have an idea as to what the possible root causes of this issue could be?

Furthermore, when I try to login in Share with the admin user, I get something like this (cropped the full stack trace to the relevant lines):
2023-01-13 09:18:19,724 ERROR [org.springframework.extensions.webscripts.AbstractRuntime] [http-nio-8080-exec-2] Exception from executeScript: null
java.lang.NullPointerException
at java.base/java.net.URI$Parser.parse(URI.java:3104)
at java.base/java.net.URI.(URI.java:600)
at java.base/java.net.URI.create(URI.java:881)
at org.apache.http.client.methods.HttpGet.(HttpGet.java:66)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.JWKPublicKeyLocator.sendRequest(JWKPublicKeyLocator.java:97)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.JWKPublicKeyLocator.getPublicKey(JWKPublicKeyLocator.java:63)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.AdapterTokenVerifier.getPublicKey(AdapterTokenVerifier.java:121)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.AdapterTokenVerifier.createVerifier(AdapterTokenVerifier.java:111)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.AdapterTokenVerifier.verifyToken(AdapterTokenVerifier.java:47)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.BearerTokenRequestAuthenticator.authenticateToken(BearerTokenRequestAuthenticator.java:103)
at de.acosix.alfresco.keycloak.deps.keycloak.adapters.BearerTokenRequestAuthenticator.authenticate(BearerTokenRequestAuthenticator.java:88)
at de.acosix.alfresco.keycloak.repo.authentication.KeycloakRemoteUserMapper.getRemoteUser(KeycloakRemoteUserMapper.java:122)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Thanks in advance for any suggestions,
Miruna

Keycloak SSO Share startup logs

share-config-custom.txt
share-logs.txt
Hello,

I am trying to use Keycloak SSO with Alfresco Community Version Number: 7.2.1 (rd28d4873-blocal). I am using Docker.

The alfresco repo works fine but I get the following error message during the alfresco share startup.
Share starts well when I do not deploy (de.acosix.alfresco.keycloak.share-1.1.0-rc7.amp)amp modue, I tested this module without any share customization but I got the same error.

Attached share config and logs files.

14-Nov-2023 08:48:51.060 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal Context [/share] startup failed due to previous errors
14-Nov-2023 08:48:51.088 SEVERE [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [share] created a ThreadLocal withkey of type [org.springframework.extensions.webscripts.processor.FTLTemplateProcessor$NonBlockingObjectWrapper$1] (value [org.springframework.extensions.webscripts.processor.FTLTemplateProcessor$NonBlockingObjectWrapper$1@79c704f5]) and a value of type [freemarker.template.DefaultObjectWrapper] (value [freemarker.template.DefaultObjectWrapper@1235199412(2.3.0, useAdaptersForContainers=false, forceLegacyNonListCollections=true, iterableSupport=falseexposureLevel=1, exposeFields=false, preferIndexedReadMethod=true, treatDefaultMethodsAsBeanMembers=false, sharedClassIntrospCache=none, ...)]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Regards
Dharmendra

Sync users problem

There are ~13.000 users inner keycloak. But when synchronization by batchSize is enabled only the first batch is printed.

We already have this settings:
keycloak.adapter.auth-server-url=https://keycloak.test/auth
keycloak.adapter.realm=COMPANY
keycloak.adapter.resource=ALFRESCO_REPO
keycloak.adapter.credentials.secret=
keycloak.synchronization.enabled=true
keycloak.synchronization.personLoadBatchSize=20
keycloak.synchronization.groupLoadBatchSize=10

Debug log shows that only the first batch was fetched, but Alfresco tools doesn't list any synchronized users or groups.

The follow message is printed after the sync is ended:
INFO [security.sync.ChainingUserRegistrySynchronizer] [main] 13,431 user(s) and 37 group(s) processed

We're using the alfresco-keycloak master branch with Alfresco 7 community version.

Do you have any idea?

Create person using a client_credential token

Hi Axel,

First i would like to thank you for this addons, I have installed modules and they works greats.

I have just a question: in our application people can be added by a non admin users and those action results in a "Permission Denied" error when request is sent to Alfresco people endpoint.

The obviousluy solution could be to authenticate an admin user before request and use genereated token for all those requests where admin role is required . But I would like to know if it's possible also to use a "client_credential" token for this endpoints.

Regards,

Stefano

A question

Hello,
in Keycloak, we have a certain groups with roles assigned to the groups.
Will Alfresco be able to know wihich content to serve or not, based on Keycloak groups with roles assigned to the groups.
So, content authorization based on keycloak groups in Alfresco is the main issue.
Thank you!

Synchronisation questions

Hello @AFaust
I've been playing with your awesome addon for some time now but I have two questions about synchronisation.

  1. As I understand, synchronisation works unidirectional - from Keycloak to Alfresco. Is it possible to do it bi-directionally?
  2. What about synchronizing currently existing users? Is it overriding them? I.e. there is the userX in Alfresco, then we create userX within Keycloak (but with different properties), how these accounts are merged?
    I'm asking because of the migration of the alfresco users to Keycloak - I thought it would be a big problem but it seems like I just have to create those users in Keycloak and everything will be fine (the users would only need to change their password). And the second thing is that after creating a user in Alfresco I can immediately assign it to proper sites, roles, groups. But if I create users in Keycloak, it is impossible. So it would be a nice workaround.

Requesting to re-authenticate with Keycloak

Dear @AFaust
I have successfully (???) installed and configured your Alfresco-Keycloak add-on in order to support integration with Keycloak Identity service.

However, I have the following situation: We have implemented a web-desktop application (https://qlack.com/webdesktop), that simulates a virtual desktop environment in one single browser window and allows multiple web applications to be integrated under the same environment. The web-desktop application is integrated with Keycloak/SSO in order to handle the authentication and authorization steps for the integrated applications.

After successfully logging in to our web-desktop application the user is presented with a list of applications, one of them being the Alfresco application. However, the user is prompted to re-enter his/hers SSO credentials.

image

Is there a way/configuration that would allow the Alfresco Share application to be accessed without the user having to re-enter his/hers credentials, since he/she are already authenticated? So what I want is to skip the above screen, since the user is already authenticated and simply navigate to this screen.
image

Thank you

Hi Alex,

Hi Alex,

I have a docker based installation of alfresco community (https://github.com/Alfresco/acs-community-deployment/blob/master/docker-compose/docker-compose.yml) and I am also interested in trying your add-on, since I have a standalone installation of keycloak (version 9.0.3 also with docker).

I have successfully cloned and built both alfresco-keycloak and alfresco-utility and copied both amp files (de.acosix.alfresco.utility.share-1.2.3.amp and de.acosix.alfresco.keycloak.share-1.1.0-rc4.amp) inside my alfresco-share:6.2.1 container (and specifically under /usr/local/tomcat/amps_share/).

However, when I restart the container and I access the some_path:8080/share/page/console/admin-console/module-package I only see "Alfresco / Google Docs Share Module".

Am I doing something wrong with the installation?

Also, regarding configuration of alfresco-global.properties and share-config-custom.xml the hyperlinks you have point to other files and I am confused as to which files to change. Also where is the location of these 2 files?

thank you in advance
-Alkis

Originally posted by @ayian2004 in #1 (comment)

Alfresco - Keycloak ..later Sync

Hi Alex,
after few weeks i finally succeeded in configure all with Alfresco 7 in Docker environment.
We built a custom Repository and Share images from your latest Utility and This .acs files.
You did a great job!!!

A question:
Is it possible to add some synchronizations later, beside initial, like a Cron job in the LDAP manner, i don't see any of keycloak.synchronization.import.cron... property existence in your docs?

A use case:
In initial sync we have a user in a particular group that has some role.
When user changes a group with some other role that change does not reflects in Alfresco, it is not synchronized even with new login if that user.

Do you have any suggestion of how we can accomplish this kind of synchronization?
THANK YOU!

How to avoid creating duplicate users from CSV and registered through identity provider?

Hi @AFaust

When creating a user directly in alfresco share via a CSV file:

imagen

User is created:

imagen

And in keycloak (the user does not exist):

imagen

When registering through the identity provider (through the "SSO via Azure" button):

imagen

imagen

imagen

Then in keycloak:

imagen

But in alfresco share a new user is created !! : <

imagen

How to make it take the same account that was created with the CSV file? Since it is intended that documents, roles etc (directly from alfresco share) are placed in the account created with the CSV file; and that when registering through the identity provider you fall into the account previously created with the CSV file.

thanks in advance, regards.

Retrieve current user token in custom services

Hello, I'm having trouble understanding how to retrieve the current user's JWT token using the alfresco-keycloak library. I noticed there are different Java classes that handle the token and its conversion with the Alfresco ticket, but I can't find the way to retrieve the token myself in the services I'm creating.

I found out these classes are all entitled to the token handling:

  • KeycloakAuthenticationComponent;
  • AccessTokenHolder and its implementation;
  • KeycloakAuthenticationService and its implementation.

If I understand well, all of them are injected as bean through the keycloak-authentication-context.xml file, but when I try to inject them in my service, they are either not available or their IDs are related to other Alfresco components, which cannot be used to actually complete my task.
Moreover, there are other components in your library that handle the token but the majority of their methods are either private or protected, so it makes it impossible for me to get what I need.

Would you explain, in the easiest way possible, how can I retrieve the JWT token for the current user using your library?

Thanks in advance!

Upgrade Keycloak v24

We are running alfresco-keycloak module with Alfresco Version 7.2 with Keycloak version v20 which works perfectly fine without any problem.

After Upgrade of Keycloak version v24 yesterday, We get the SSO login page where it redirect back to Alfresco login page after keycloak authentication again and again.
We have not enforced SSO login, Users(external users) have option login with basic auth and keycloak SSO( Company Employee) as well.

can you please suggest what could be wrong ....

Keycloak logout hook

I want a user after successfully login in using the keycloak SSO service (implemented through this plugin), when logging out from Keycloak to also be logout from the Alfresco service. Hence I am looking if Alfresco-keycloak offers "logout hooks from Keycloak to get notified when a global logout takes place".

Thank you

Incompatible with ACS 7.4

I tried to follow the documentation and I encounter some difficulties to install the module on Alfresco 7.4.

As mentioned in the issue #23 I had to use de.acosix.alfresco.utility.repo instead of de.acosix.alfresco.utility.core.repo

Then for applying the amps to the .war, I couldn't use directly :

RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install \
              $TOMCAT_DIR/amps $TOMCAT_DIR/webapps/alfresco -directory -nobackup -force

because de.acosix.alfresco.utility.core.repo need to be applied before de.acosix.alfresco.keycloak.repo

To do this, I did the following:

RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install \
              $TOMCAT_DIR/amps/de.acosix.alfresco.utility.repo-1.3.2.amp $TOMCAT_DIR/webapps/alfresco -nobackup -force -verbose

# Installation des amps
RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install \
              $TOMCAT_DIR/amps $TOMCAT_DIR/webapps/alfresco -directory -nobackup -force

After that, the module can be applied at image build and alfresco can start.

But I encounter an another error due to some transformer bean not present in the classpath. I remembered that alfresco 7.3+ had some breaking changes with that in particular.

As this error was caused by de.acosix.alfresco.keycloak.repo version 1.2.5 (the version mentioned in the documentation and used in the pom.xml)

I changed the version of de.acosix.alfresco.keycloak.repo from 1.2.5 to 1.3.2 (idk which version started to be compatible with acs 7.3+ so I took the last one)

But couldn't apply the amp de.acosix.alfresco.keycloak.repo because it requires de.acosix.alfresco.utility.core.repo version 1.2.5 as described in module.properties

I had to clone the project, change in module.properties the version from 1.2.5-* to 1.3.2 and in the parent pom.xml
<acosix.utility.version>1.2.5</acosix.utility.version> to <acosix.utility.version>1.3.2</acosix.utility.version>

then mvn clean install and voilà.

The module is installing, the subsystem is starting and my users from Keycloak are sync into Alfresco!

Now I can login to Alfresco with mu users from Keycloak (but only with basic auth) tested with Postman.
If I want to login to alfresco using a JWT bearer token provided by Keycloak, I have the following error:

http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/262a0ad3-961a-4af0-9b85-fdbc8b212ac9

{
    "error": {
        "errorKey": "framework.exception.ApiDefault",
        "statusCode": 401,
        "briefSummary": "10100052 Authorization 'bearer' not supported.",
        "stackTrace": "Pour des raisons de sécurité, le traçage de la pile n'est plus affiché, mais la propriété est conservée dans les versions précédente",
        "descriptionURL": "https://api-explorer.alfresco.com"
    }
}

Here is my subsystem configuration:

keycloak.authentication.enabled=true
keycloak.authentication.sso.enabled=true
keycloak.authentication.handlePublicApi=true
keycloak.authentication.allowTicketLogons=true
keycloak.authentication.allowHttpBasicLogon=true
keycloak.authentication.allowUserNamePasswordLogin=true
keycloak.authentication.mapAuthorities=true
keycloak.authentication.mapPersonPropertiesOnLogin=true

keycloak.synchronization.enabled=true

keycloak.adapter.auth-server-url=http://pc-dev-lx-svallet.cpage.fr:7080
#keycloak.adapter.forced-route-url=
keycloak.adapter.realm=ged
keycloak.adapter.resource=alfresco-repo
keycloak.adapter.credentials.secret=qV2bjh6THZawtJ801tLp80AKWvvC0Y7t
keycloak.adapter.verify-token-audience=true

So why can't I login with a bearer token to the alfresco repository?

Help me!,I can't configure

Dera!

According to the configuration, I cannot operate!
Can you provide a josn file or detailed configuration?

Sorry, I just learned keycloak and slfresco.

Hope to receive a reply!
thank you very much!

failed verification of token: Token is not active

First, I would like to thank you for this awesome addon.
I have installed modules and they works but when i restart alfresco server it doesn't work and it show me this error on alfresco.log :
2023-04-14 03:12:59,942 ERROR [org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer] [main] Synchronization aborted due to error de.acosix.alfresco.keycloak.repo.token.AccessTokenVerificationException: 03140036 Failed to verify token at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.verifyAccessTokenResponse(AccessTokenClient.java:228) at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.obtainAccessToken(AccessTokenClient.java:79) at de.acosix.alfresco.keycloak.repo.token.AccessTokenServiceImpl.obtainAccessToken(AccessTokenServiceImpl.java:67) at de.acosix.alfresco.keycloak.repo.client.AbstractIDMClientImpl.getValidAccessTokenForRequest(AbstractIDMClientImpl.java:332) at de.acosix.alfresco.keycloak.repo.client.AbstractIDMClientImpl.processGenericGet(AbstractIDMClientImpl.java:208) at de.acosix.alfresco.keycloak.repo.client.IdentitiesClientImpl.countGroups(IdentitiesClientImpl.java:72) at de.acosix.alfresco.keycloak.repo.sync.KeycloakUserRegistry.getGroups(KeycloakUserRegistry.java:182) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.syncWithPlugin(ChainingUserRegistrySynchronizer.java:993) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.synchronizeInternal(ChainingUserRegistrySynchronizer.java:739) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.access$15(ChainingUserRegistrySynchronizer.java:474) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer$7.doWork(ChainingUserRegistrySynchronizer.java:2138) at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:602) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onBootstrap(ChainingUserRegistrySynchronizer.java:2132) at org.springframework.extensions.surf.util.AbstractLifecycleBean.onApplicationEvent(AbstractLifecycleBean.java:56) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onApplicationEvent(ChainingUserRegistrySynchronizer.java:2495) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ChildApplicationContext.publishEvent(ChildApplicationContextFactory.java:569) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ApplicationContextState.start(ChildApplicationContextFactory.java:824) at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.start(AbstractPropertyBackedBean.java:1098) at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.onApplicationEvent(AbstractPropertyBackedBean.java:637) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEventInternal(SafeApplicationEventMulticaster.java:232) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:197) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:217) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) at org.alfresco.web.app.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:70) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4493) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4939) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:662) at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:689) at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1888) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:582) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:472) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1617) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:318) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:898) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:795) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:871) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:249) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:428) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:917) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:772) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478) Caused by: de.acosix.alfresco.keycloak.deps.keycloak.exceptions.TokenNotActiveException: Token is not active at de.acosix.alfresco.keycloak.deps.keycloak.TokenVerifier$2.test(TokenVerifier.java:86) at de.acosix.alfresco.keycloak.deps.keycloak.TokenVerifier.verify(TokenVerifier.java:473) at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.AdapterTokenVerifier.verifyTokens(AdapterTokenVerifier.java:70) at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.verifyAccessTokenResponse(AccessTokenClient.java:224) ... 76 more 2023-04-14 03:13:00,083 ERROR [org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer] [main] Synchronization aborted due to error de.acosix.alfresco.keycloak.repo.token.AccessTokenVerificationException: 03140036 Failed to verify token at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.verifyAccessTokenResponse(AccessTokenClient.java:228) at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.obtainAccessToken(AccessTokenClient.java:79) at de.acosix.alfresco.keycloak.repo.token.AccessTokenServiceImpl.obtainAccessToken(AccessTokenServiceImpl.java:67) at de.acosix.alfresco.keycloak.repo.client.AbstractIDMClientImpl.getValidAccessTokenForRequest(AbstractIDMClientImpl.java:332) at de.acosix.alfresco.keycloak.repo.client.AbstractIDMClientImpl.processGenericGet(AbstractIDMClientImpl.java:208) at de.acosix.alfresco.keycloak.repo.client.IdentitiesClientImpl.countGroups(IdentitiesClientImpl.java:72) at de.acosix.alfresco.keycloak.repo.sync.KeycloakUserRegistry.getGroups(KeycloakUserRegistry.java:182) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.syncWithPlugin(ChainingUserRegistrySynchronizer.java:993) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.synchronizeInternal(ChainingUserRegistrySynchronizer.java:739) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.access$15(ChainingUserRegistrySynchronizer.java:474) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer$7.doWork(ChainingUserRegistrySynchronizer.java:2138) at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:602) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onBootstrap(ChainingUserRegistrySynchronizer.java:2132) at org.springframework.extensions.surf.util.AbstractLifecycleBean.onApplicationEvent(AbstractLifecycleBean.java:56) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onApplicationEvent(ChainingUserRegistrySynchronizer.java:2495) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ChildApplicationContext.publishEvent(ChildApplicationContextFactory.java:569) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ApplicationContextState.start(ChildApplicationContextFactory.java:824) at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.start(AbstractPropertyBackedBean.java:1098) at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.onApplicationEvent(AbstractPropertyBackedBean.java:637) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEventInternal(SafeApplicationEventMulticaster.java:232) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:197) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:217) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) at org.alfresco.web.app.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:70) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4493) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4939) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:662) at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:689) at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1888) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:582) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:472) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1617) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:318) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:898) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:795) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:871) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:249) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:428) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:917) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:772) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478) Caused by: de.acosix.alfresco.keycloak.deps.keycloak.exceptions.TokenNotActiveException: Token is not active at de.acosix.alfresco.keycloak.deps.keycloak.TokenVerifier$2.test(TokenVerifier.java:86) at de.acosix.alfresco.keycloak.deps.keycloak.TokenVerifier.verify(TokenVerifier.java:473) at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.AdapterTokenVerifier.verifyTokens(AdapterTokenVerifier.java:70) at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.verifyAccessTokenResponse(AccessTokenClient.java:224) ... 76 more 2023-04-14 03:13:00,112 WARN [org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer] [main] Failed initial synchronize with user registries de.acosix.alfresco.keycloak.repo.token.AccessTokenVerificationException: 03140036 Failed to verify token at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.verifyAccessTokenResponse(AccessTokenClient.java:228) at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.obtainAccessToken(AccessTokenClient.java:79) at de.acosix.alfresco.keycloak.repo.token.AccessTokenServiceImpl.obtainAccessToken(AccessTokenServiceImpl.java:67) at de.acosix.alfresco.keycloak.repo.client.AbstractIDMClientImpl.getValidAccessTokenForRequest(AbstractIDMClientImpl.java:332) at de.acosix.alfresco.keycloak.repo.client.AbstractIDMClientImpl.processGenericGet(AbstractIDMClientImpl.java:208) at de.acosix.alfresco.keycloak.repo.client.IdentitiesClientImpl.countGroups(IdentitiesClientImpl.java:72) at de.acosix.alfresco.keycloak.repo.sync.KeycloakUserRegistry.getGroups(KeycloakUserRegistry.java:182) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.syncWithPlugin(ChainingUserRegistrySynchronizer.java:993) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.synchronizeInternal(ChainingUserRegistrySynchronizer.java:739) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.access$15(ChainingUserRegistrySynchronizer.java:474) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer$7.doWork(ChainingUserRegistrySynchronizer.java:2138) at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:602) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onBootstrap(ChainingUserRegistrySynchronizer.java:2132) at org.springframework.extensions.surf.util.AbstractLifecycleBean.onApplicationEvent(AbstractLifecycleBean.java:56) at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onApplicationEvent(ChainingUserRegistrySynchronizer.java:2495) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ChildApplicationContext.publishEvent(ChildApplicationContextFactory.java:569) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ApplicationContextState.start(ChildApplicationContextFactory.java:824) at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.start(AbstractPropertyBackedBean.java:1098) at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.onApplicationEvent(AbstractPropertyBackedBean.java:637) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEventInternal(SafeApplicationEventMulticaster.java:232) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:197) at org.alfresco.repo.management.SafeApplicationEventMulticaster.multicastEvent(SafeApplicationEventMulticaster.java:217) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) at org.alfresco.web.app.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:70) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4493) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4939) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:662) at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:689) at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1888) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:582) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:472) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1617) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:318) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:898) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:795) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:871) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:249) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:428) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:917) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:772) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478) Caused by: de.acosix.alfresco.keycloak.deps.keycloak.exceptions.TokenNotActiveException: Token is not active at de.acosix.alfresco.keycloak.deps.keycloak.TokenVerifier$2.test(TokenVerifier.java:86) at de.acosix.alfresco.keycloak.deps.keycloak.TokenVerifier.verify(TokenVerifier.java:473) at de.acosix.alfresco.keycloak.deps.keycloak.adapters.rotation.AdapterTokenVerifier.verifyTokens(AdapterTokenVerifier.java:70) at de.acosix.alfresco.keycloak.repo.token.AccessTokenClient.verifyAccessTokenResponse(AccessTokenClient.java:224) ... 76 more
and this is the log of share.log :
2023-04-14 03:16:10,707 ERROR [de.acosix.alfresco.keycloak.deps.keycloak.adapters.OAuthRequestAuthenticator] [ajp-nio-127.0.0.1-8009-exec-6] failed verification of token: Token is not active 2023-04-14 03:16:10,711 WARN [de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter] [ajp-nio-127.0.0.1-8009-exec-6] Keycloak authentication failed due to <missing AuthenticationError details in request context> 2023-04-14 03:16:11,790 INFO [org.alfresco.web.site.EditionInterceptor] [ajp-nio-127.0.0.1-8009-exec-7] Successfully retrieved license information from Alfresco.
Thanks for your time.

Problem with redirecting to requested URL

The "Login" button works fine, but after clicking "Single Sign On" button, the redirect_uri param (taken from form's hidden input element) is always "https://example.com/share/page/" instead of the requested URL (i.e. https://example.com/share/page/site/example/document-details?nodeRef=workspace://SpacesStore/abcdef-9754-42f7-20dc-8db73dc5c158).
I checked prepareLoginFormEnhancement(context, req, res) method from KeycloakAuthenticationFilter.java and I noticed that 1) captureFacade.getRequest().getURI(), 2) redirect_uri param from redirects.get(0) and 3) req.getRequestURL() - they always return "https://example.com/share/page?" instead of requested URL.
The problem disappears when I remove external-auth line from "alfresco" endpoint in the share-config-custom.xml (but then obviously Keycloak does not work).
Does anyone also have the same problem or did I just messed up with the configuration?
As a workaround, I temporarily modified login.get.js to use successUrl (taken from context.properties.alfRedirectUrl)
But still, I cannot force it to add params to the url, which is problematic with the Document library links (i.e. filter param in the https://example.com/share/page/repository#filter=path%7C%2FData%2520dictionary%2FQuick%2520Share%2520Link%2520Expiry%2520Actions%2520Space%7C&page=1)

Support fot Alfresco 23.x?

Hello @AFaust,
Will this module have or already have support for version 23 of alfresco? I use version 23.0.6 of keycloak.

Thank you very much for your work!!

Passing roles/groups from Keycloak to Alfresco

Hi @AFaust
Is there a way to map some basic roles (admin, non-admin) from Keycloak to Alfresco, so that after successful SSO login users with the admin roles are given access to the admin tools, of Alfresco?
Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.