This module provides implementation samples and should not be used as is. This module is not supported.
- Edit
pom.xml
- Add
jahia-oauth
dependency<dependency> <groupId>org.jahia.modules</groupId> <artifactId>jahia-oauth</artifactId> <version>3.3.0-SNAPSHOT</version> <scope>provided</scope> </dependency>
- Add
jahia-oauth
dependency<dependency> <groupId>org.jahia.modules</groupId> <artifactId>jahia-authentication</artifactId> <version>1.1.0</version> <scope>provided</scope> </dependency>
- Add
com.github.scribejava
dependency<dependency> <groupId>com.github.scribejava</groupId> <artifactId>scribejava-apis</artifactId> <version>6.8.1</version> <scope>provided</scope> </dependency>
- Be carefeul to set the
<scope>
to provided
- Add
- Add
jahia-oauth
&jahia-authentication
dependency- Edit
pom.xml
<jahia-depends>default,jahia-authentication,jahia-oauth</jahia-depends>
- Edit
repository.xml
<sample-oauth j:dependencies="default jahia-authentication jahia-oauth" />
- Edit
- Enable modules on the site
- Go to Administration > Modules and extensions > Modules
- Enable module
jahia-oauth
- Enable a module mapper, for instance JCR Authentication Provider
jcr-auth-provider
-
Create OSGI Service Component to extend
jahia-authentication
services-
Implement
ConnectorService
:- Annotate the service component
@Component(service = {KeycloakConnectorImpl.class, OAuthConnectorService.class, ConnectorService.class}, property = {JahiaAuthConstants.CONNECTOR_SERVICE_NAME + "=" + KeycloakConnectorImpl.KEY}, immediate = true)
-
Add the custom connector on activation
There is two ways to add connectors.
Add an instance of the connector if it does not have custom property:
@Activate private void onActivate() { jahiaOAuthService.addOAuthDefaultApi20(KEY, StravaApi20.instance()); }
Or wrap the connector into a connector builder which will allow to manage custom properties and manage these properties per site
public class AzureConnectorBuilder implements JahiaOAuthAPIBuilder { private static final String TENANT_ID = "tenantID"; @Override public DefaultApi20 build(ConnectorConfig connectorConfig) { return MicrosoftAzureActiveDirectory20Api.custom(connectorConfig.getProperty(TENANT_ID)); } }
The connector builder have a
build
method where it's possible to instantiate dynamically a custom connector with the per site configuration. Thebuild
method will be called automatically when the connector will be required.Then you simply have to add the connector builder into the list of available connectors.
@Activate private void onActivate() { jahiaOAuthService.addOAuthDefaultApi20(KEY, new AzureConnectorBuilder()); }
-
Remove the custom connector on deactivation
@Deactivate private void onDeactivate() { jahiaOAuthService.removeOAuthDefaultApi20(KEY); }
- Specifiy the protetedResourceURL (URL to get the user info)
- Specify the properties in the JSON result to enable OAuth Data Mapping
-
Implement 2 Jahia Actions
ConnectToOAuthProvider
: used by the UI component (usually a login button)OAuthCallback
: set up in the site settings components form- Inject
JahiaOAuthService
andSettingsService
@Reference(service = JahiaOAuthService.class) private void refJahiaOAuthService(JahiaOAuthService jahiaOAuthService) { this.jahiaOAuthService = jahiaOAuthService; } @Reference(service = SettingsService.class) private void refSettingsService(SettingsService settingsService) { this.settingsService = settingsService; }
-
Edit
pom.xml
as JAVA classes for service component are annotated with@Component
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <_dsannotations>*</_dsannotations> </instructions> </configuration> </plugin> </plugins> </build>
-
-
Add site settings component
- Edit
definitions.cnd
[soauthnt:keycloakOAuthView] > jnt:content, jmix:authConnectorSettingView
- Create a default view
- Include your Angular Controller
<template:addResources type="javascript" resources="auth/keycloak-controller.js"/> <md-card ng-controller="KeycloakController as keycloak">
- Edit
repository.xml
<keycloak-oauth-view j:defaultTemplate="false" j:hiddenTemplate="true" j:invertCondition="false" j:requireLoggedUser="false" j:requirePrivilegedUser="false" jcr:primaryType="jnt:contentTemplate"> <pagecontent jcr:primaryType="jnt:contentList"> <keycloakoauthview jcr:primaryType="soauthnt:keycloakOAuthView"/> </pagecontent> </keycloak-oauth-view>
- Edit
-
Internationalization
- Edit
pom.xml
and define a dictionaryName
<build> <plugins> <plugin> <artifactId>jahia-maven-plugin</artifactId> <groupId>org.jahia.server</groupId> <executions> <execution> <id>i18n2js</id> <goals> <goal>javascript-dictionary</goal> </goals> <configuration> <dictionaryName>sampleoauthi18n</dictionaryName> </configuration> </execution> </executions> </plugin> </plugins> </build>
- Update the Angular controller with the dictionaryName
i18nService.addKey(sampleoauthi18n);
- Update your default view for the site component
<template:addResources type="javascript" resources="i18n/sample-oauth-i18n_${renderContext.UILocale}.js" var="i18nJSFile"/> <c:if test="${empty i18nJSFile}"> <template:addResources type="javascript" resources="i18n/sample-oauth-i18n_en.js"/> </c:if>
- Edit
-
UI integration
- Edit
definitions.cnd
[soauthnt:keycloakButton] > jnt:content, joamix:oauthButtonConnector
- Add a default view and create a JavaScript function to call asynchronously your custom implementation
<template:addResources> <script> function connectToKeycloak${fn:replace(currentNode.identifier, '-', '')}() { var popup = window.open('', "Keycloak Authorization", "menubar=no,status=no,scrollbars=no,width=1145,height=725,modal=yes,alwaysRaised=yes"); var xhr = new XMLHttpRequest(); xhr.open('GET', '<c:url value="${url.base}${renderContext.site.home.path}"/>.connectToKeycloakAction.do'); xhr.setRequestHeader('Accept', 'application/json;'); xhr.onreadystatechange = () => { if (xhr.readyState !== 4 || xhr.status !== 200) { return; } popup.location.href = JSON.parse(xhr.responseText).authorizationUrl; window.addEventListener('message', event => { if (event.data.authenticationIsDone) { setTimeout(() => { popup.close(); if (event.data.isAuthenticate) { window.location.search = 'site=${renderContext.site.siteKey}'; } }, 3000); } }); }; xhr.send(); } </script> </template:addResources>
- Add a custom properties file to set up cache parameters
cache.mainResource=true cache.perUser=true
- Edit