Repository: karaf Updated Branches: refs/heads/master 7a84233c0 -> c2722856f
[KARAF-5282] Add Syncope 2.x support in the SyncopeLoginModule Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/c2722856 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/c2722856 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/c2722856 Branch: refs/heads/master Commit: c2722856f62bf58ad584e5fd3a9875b7ad7c9bbc Parents: 7a84233 Author: Jean-Baptiste Onofré <[email protected]> Authored: Wed Aug 2 18:54:33 2017 +0200 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Wed Aug 2 18:54:33 2017 +0200 ---------------------------------------------------------------------- jaas/modules/pom.xml | 1 + .../modules/syncope/SyncopeLoginModule.java | 36 ++++++++++++++-- .../modules/syncope/SyncopeLoginModuleTest.java | 45 +++++++++++++++++++- .../developer-guide/security-framework.adoc | 5 +++ 4 files changed, 81 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/c2722856/jaas/modules/pom.xml ---------------------------------------------------------------------- diff --git a/jaas/modules/pom.xml b/jaas/modules/pom.xml index 19e058b..fa4c264 100644 --- a/jaas/modules/pom.xml +++ b/jaas/modules/pom.xml @@ -155,6 +155,7 @@ <Private-Package> org.apache.karaf.jaas.modules.impl, org.apache.felix.utils.properties, + org.apache.felix.utils.json, org.apache.karaf.util, org.apache.http*, org.apache.commons.codec* http://git-wip-us.apache.org/repos/asf/karaf/blob/c2722856/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModule.java ---------------------------------------------------------------------- diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModule.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModule.java index aa977e4..3d6eb66 100644 --- a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModule.java +++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModule.java @@ -14,6 +14,7 @@ */ package org.apache.karaf.jaas.modules.syncope; +import org.apache.felix.utils.json.JSONParser; import org.apache.http.HttpStatus; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; @@ -42,14 +43,17 @@ public class SyncopeLoginModule extends AbstractKarafLoginModule { private final static Logger LOGGER = LoggerFactory.getLogger(SyncopeLoginModule.class); public final static String ADDRESS = "address"; + public final static String VERSION = "version"; public final static String ADMIN_USER = "admin.user"; // for the backing engine public final static String ADMIN_PASSWORD = "admin.password"; // for the backing engine private String address; + private String version; public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { super.initialize(subject, callbackHandler, options); address = (String) options.get(ADDRESS); + version = (String) options.get(VERSION); } public boolean login() throws LoginException { @@ -80,7 +84,11 @@ public class SyncopeLoginModule extends AbstractKarafLoginModule { Credentials creds = new UsernamePasswordCredentials(user, password); client.getCredentialsProvider().setCredentials(AuthScope.ANY, creds); HttpGet get = new HttpGet(address + "/users/self"); - get.setHeader("Content-Type", "application/xml"); + if (version.equals("2.x") || version.equals("2")) { + get.setHeader("Content-Type", "application/json"); + } else { + get.setHeader("Content-Type", "application/xml"); + } List<String> roles = new ArrayList<>(); try { CloseableHttpResponse response = client.execute(get); @@ -93,7 +101,11 @@ public class SyncopeLoginModule extends AbstractKarafLoginModule { LOGGER.debug("Populating principals with user"); principals.add(new UserPrincipal(user)); LOGGER.debug("Retrieving user {} roles", user); - roles = extractingRoles(EntityUtils.toString(response.getEntity())); + if (version.equals("2.x") || version.equals("2")) { + roles = extractingRolesSyncope2(EntityUtils.toString(response.getEntity())); + } else { + roles = extractingRolesSyncope1(EntityUtils.toString(response.getEntity())); + } } catch (Exception e) { LOGGER.error("User {} authentication failed", user, e); throw new LoginException("User " + user + " authentication failed: " + e.getMessage()); @@ -108,13 +120,13 @@ public class SyncopeLoginModule extends AbstractKarafLoginModule { } /** - * Extract the user roles from the Syncope entity response. + * Extract the user roles from the XML provided by Syncope 1.x. * * @param response the HTTP response from Syncope. * @return the list of user roles. * @throws Exception in case of extraction failure. */ - protected List<String> extractingRoles(String response) throws Exception { + protected List<String> extractingRolesSyncope1(String response) throws Exception { List<String> roles = new ArrayList<>(); if (response != null && !response.isEmpty()) { // extract the <memberships> element if it exists @@ -143,6 +155,22 @@ public class SyncopeLoginModule extends AbstractKarafLoginModule { return roles; } + /** + * Extract the user roles from the JSON provided by Syncope 2.x. + * + * @param response the HTTP response from Syncope. + * @return the list of user roles. + * @throws Exception in case of extractiong failure. + */ + protected List<String> extractingRolesSyncope2(String response) throws Exception { + List<String> roles = new ArrayList<>(); + if (response != null && !response.isEmpty()) { + JSONParser parser = new JSONParser(response); + return (List<String>) parser.getParsed().get("roles"); + } + return roles; + } + public boolean abort() { return true; } http://git-wip-us.apache.org/repos/asf/karaf/blob/c2722856/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModuleTest.java ---------------------------------------------------------------------- diff --git a/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModuleTest.java b/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModuleTest.java index eca0818..560879a 100644 --- a/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModuleTest.java +++ b/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/syncope/SyncopeLoginModuleTest.java @@ -24,7 +24,7 @@ import java.util.List; public class SyncopeLoginModuleTest { @Test - public void testRolesExtraction() throws Exception { + public void testRolesExtractionSyncope1() throws Exception { String syncopeResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + "<user>\n" + " <attributes>\n" + @@ -96,7 +96,48 @@ public class SyncopeLoginModuleTest { " <username>karaf</username>\n" + "</user>\n"; SyncopeLoginModule syncopeLoginModule = new SyncopeLoginModule(); - List<String> roles = syncopeLoginModule.extractingRoles(syncopeResponse); + List<String> roles = syncopeLoginModule.extractingRolesSyncope1(syncopeResponse); + Assert.assertEquals(2, roles.size()); + Assert.assertEquals("admin", roles.get(0)); + Assert.assertEquals("another", roles.get(1)); + } + + @Test + public void testRolesExtractionSyncope2() throws Exception { + String syncopeResponse = "{\n" + "\n" + + " \"@class\":\"org.apache.syncope.common.lib.to.UserTO\",\n" + "\n" + + " \"creator\":\"admin\",\n" + "\n" + + " \"creationDate\":\"2017-07-31T08:36:41.000+0000\",\n" + "\n" + + " \"lastModifier\":\"admin\",\n" + "\n" + + " \"lastChangeDate\":\"2017-08-01T08:46:19.236+0000\",\n" + "\n" + + " \"key\":\"e5a131b0-eb66-4115-a131-b0eb66511579\",\n" + "\n" + + " \"type\":\"USER\",\n" + "\n" + " \"realm\":\"/karaf\",\n" + "\n" + + " \"status\":\"created\",\n" + "\n" + " \"password\":null,\n" + "\n" + + " \"token\":null,\n" + "\n" + " \"tokenExpireTime\":null,\n" + "\n" + + " \"username\":\"karaf\",\n" + "\n" + + " \"lastLoginDate\":\"2017-08-01T08:46:19.224+0000\",\n" + "\n" + + " \"changePwdDate\":null,\n" + "\n" + " \"failedLogins\":0,\n" + "\n" + + " \"securityQuestion\":null,\n" + "\n" + " \"securityAnswer\":null,\n" + "\n" + + " \"mustChangePassword\":false,\n" + "\n" + " \"auxClasses\":[\n" + "\n" + + " \n" + "\n" + " ],\n" + "\n" + " \"plainAttrs\":[\n" + "\n" + " \n" + "\n" + + " ],\n" + "\n" + " \"derAttrs\":[\n" + "\n" + " \n" + "\n" + " ],\n" + "\n" + + " \"virAttrs\":[\n" + "\n" + " \n" + "\n" + " ],\n" + "\n" + + " \"resources\":[\n" + "\n" + " \n" + "\n" + " ],\n" + "\n" + + " \"roles\":[\n" + "\n" + " \"admin\", \"another\"\n" + "\n" + " ],\n" + + "\n" + + " \"dynRoles\":[\n" + "\n" + " \"admin\"\n" + "\n" + " ],\n" + "\n" + + " \"relationships\":[\n" + "\n" + " \n" + "\n" + " ],\n" + "\n" + + " \"memberships\":[\n" + "\n" + " {\n" + "\n" + + " \"type\":\"Membership\",\n" + "\n" + + " \"rightType\":\"GROUP\",\n" + "\n" + + " \"rightKey\":\"3847aa78-3202-4d8f-87aa-7832026d8fba\",\n" + "\n" + + " \"groupName\":\"manager\",\n" + "\n" + " \"plainAttrs\":[\n" + + "\n" + " \n" + "\n" + " ],\n" + "\n" + " \"derAttrs\":[\n" + "\n" + + " \n" + "\n" + " ],\n" + "\n" + " \"virAttrs\":[\n" + "\n" + " \n" + + "\n" + " ]\n" + "\n" + " }\n" + "\n" + " ],\n" + "\n" + + " \"dynGroups\":[\n" + "\n" + " \n" + "\n" + " ]\n" + "\n" + "}"; + SyncopeLoginModule syncopeLoginModule = new SyncopeLoginModule(); + List<String> roles = syncopeLoginModule.extractingRolesSyncope2(syncopeResponse); Assert.assertEquals(2, roles.size()); Assert.assertEquals("admin", roles.get(0)); Assert.assertEquals("another", roles.get(1)); http://git-wip-us.apache.org/repos/asf/karaf/blob/c2722856/manual/src/main/asciidoc/developer-guide/security-framework.adoc ---------------------------------------------------------------------- diff --git a/manual/src/main/asciidoc/developer-guide/security-framework.adoc b/manual/src/main/asciidoc/developer-guide/security-framework.adoc index 962bd75..d0ac7da 100644 --- a/manual/src/main/asciidoc/developer-guide/security-framework.adoc +++ b/manual/src/main/asciidoc/developer-guide/security-framework.adoc @@ -610,6 +610,9 @@ The Syncope login module just requires one parameter: |`address` |Location of the Syncope REST API +|`version` +| Syncope backend version (could by "1.x" or "2.x" + |`admin.user` |Admin username to administrate Syncope (only required by the backend engine) @@ -623,6 +626,7 @@ The following snippet shows how to use Syncope with the karaf realm: <jaas:config name="karaf" rank="2"> <jaas:module className="org.apache.karaf.jaas.modules.syncope.SyncopeLoginModule" flags="required"> address=http://localhost:9080/syncope/cxf + version=1.x admin.user=admin admin.password=password </jaas:module> @@ -647,6 +651,7 @@ For instance, the following blueprint descriptor enables the SyncopeLoginModule <jaas:module className="org.apache.karaf.jaas.modules.syncope.SyncopeLoginModule" flags="required"> address=http://localhost:9080/syncope/cxf + version=1.x admin.user=admin admin.password=password </jaas:module>
