diff options
Diffstat (limited to 'id/server/modules/moa-id-module-dummyAuth/src/main/java/at')
5 files changed, 594 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/ConfigurationProperties.java b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/ConfigurationProperties.java new file mode 100644 index 000000000..b42e5b0f7 --- /dev/null +++ b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/ConfigurationProperties.java @@ -0,0 +1,58 @@ +/* + * Copyright 2021 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.auth.dummy; + +import java.util.Collection; +import java.util.Set; + +import com.google.common.collect.Sets; + +import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; + +public class ConfigurationProperties { + + // configuration properties + private static final String MODULE_PREFIX = "modules.dummyauth."; + + public static final String PROP_MODULE_ENABLED = MODULE_PREFIX + "enabled"; + public static final String PROP_MODULE_SP_PREFIX = MODULE_PREFIX + "sp"; + public static final String PROP_MODULE_IDENTITY_STORE_PATH = MODULE_PREFIX + "identity.store.path"; + + // http parameter + public static final String HTTP_PARAM_START_DUMMY_AUTH = "dummyauth"; + + // configuration filetype + public static final String ALLOWED_FILE_TYPE = "json"; + + + //minimum required attributes + public static final Collection<String> MINIMUM_REQ_ATTRIBUTES = Sets.newHashSet( + PVPAttributeDefinitions.BIRTHDATE_NAME, + PVPAttributeDefinitions.GIVEN_NAME_NAME, + PVPAttributeDefinitions.PRINCIPAL_NAME_NAME, + PVPAttributeDefinitions.BPK_NAME); + + private ConfigurationProperties() { + // hide constructor or static class + } +} diff --git a/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/DummyIdentityAuthModule.java b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/DummyIdentityAuthModule.java new file mode 100644 index 000000000..e2f550736 --- /dev/null +++ b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/DummyIdentityAuthModule.java @@ -0,0 +1,152 @@ +/* + * Copyright 2021 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.auth.dummy; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; +import at.gv.egiz.eaaf.core.api.idp.auth.IAuthenticationManager; +import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +public class DummyIdentityAuthModule implements AuthModule { + + private int priority = 2; + + @Autowired(required = true) + protected IConfigurationWithSP authConfig; + @Autowired(required = true) + private IAuthenticationManager authManager; + + private Collection<String> uniqueIDsDummyAuthEnabled; + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getPriority() + */ + @Override + public int getPriority() { + return priority; + } + + /** + * Sets the priority of this module. Default value is {@code 0}. + * + * @param priority The priority. + */ + public void setPriority(int priority) { + this.priority = priority; + } + + @PostConstruct + private void initialDummyAuthWhiteList() { + if (authConfig.getBasicConfigurationBoolean(ConfigurationProperties.PROP_MODULE_ENABLED, false)) { + Logger.info("AuthModule for 'dummy-identities' is enabled"); + + // load allowed service-provider Id's + uniqueIDsDummyAuthEnabled = authConfig.getBasicConfigurationWithPrefix( + ConfigurationProperties.PROP_MODULE_SP_PREFIX).values().stream() + .filter(el -> StringUtils.isNotEmpty(el)) + .collect(Collectors.toSet()); + + if (!uniqueIDsDummyAuthEnabled.isEmpty()) { + Logger.info("Dummy authentication is enabled for ...."); + uniqueIDsDummyAuthEnabled.forEach(el -> Logger.info(" EntityID: " + el)); + + } + + // TODO: do we need a selection parameter from external + authManager.addParameterNameToWhiteList(ConfigurationProperties.HTTP_PARAM_START_DUMMY_AUTH); + + } else { + uniqueIDsDummyAuthEnabled = Collections.emptySet(); + Logger.info("AuthModule for 'dummy-identities' is disabled"); + + } + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv. + * egovernment.moa.id.process.api.ExecutionContext) + */ + @Override + public String selectProcess(ExecutionContext context, IRequest pendingReq) { + + if (authConfig.getBasicConfigurationBoolean(ConfigurationProperties.PROP_MODULE_ENABLED, false)) { + final String spEntityID = pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(); + Logger.trace("Check dummy-auth for SP: " + spEntityID); + if (uniqueIDsDummyAuthEnabled.contains(spEntityID)) { + final Serializable flagObj = context.get(ConfigurationProperties.HTTP_PARAM_START_DUMMY_AUTH); + if (flagObj instanceof String && Boolean.valueOf((String) flagObj)) { + Logger.info("Starting Dummy-Identity authentication for SP: " + spEntityID); + return "dummyIdentityAuthentication"; + + } else { + Logger.debug("Dummy-Identity authentication flag not 'true'. Skip it ... "); + + } + + } else { + Logger.debug("Unique SP-Id: " + spEntityID + + " is not in whitelist for Dummy-Identity authentication."); + + } + + } else { + Logger.trace("Dummy-Identity authentication is disabled"); + + } + + return null; + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() + */ + @Override + public String[] getProcessDefinitions() { + return new String[] { "classpath:/dummy_identity_auth.process.xml" }; + } + +} diff --git a/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/DummyIdentityAuthSpringResourceProvider.java b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/DummyIdentityAuthSpringResourceProvider.java new file mode 100644 index 000000000..d8218b7f1 --- /dev/null +++ b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/DummyIdentityAuthSpringResourceProvider.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.auth.dummy; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +/** + * @author tlenz + * + */ +public class DummyIdentityAuthSpringResourceProvider implements SpringResourceProvider { + + /* (non-Javadoc) + * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getResourcesToLoad() + */ + @Override + public Resource[] getResourcesToLoad() { + ClassPathResource authConfig = new ClassPathResource("/moaid_dummy_identity_auth.beans.xml", DummyIdentityAuthSpringResourceProvider.class); + return new Resource[] {authConfig}; + } + + /* (non-Javadoc) + * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getPackagesToScan() + */ + @Override + public String[] getPackagesToScan() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see at.gv.egiz.components.spring.api.SpringResourceProvider#getName() + */ + @Override + public String getName() { + return "Module for 'Dummy Authentication'"; + } + +} diff --git a/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/service/DummyIdentityService.java b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/service/DummyIdentityService.java new file mode 100644 index 000000000..9bb961e47 --- /dev/null +++ b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/service/DummyIdentityService.java @@ -0,0 +1,182 @@ +package at.gv.egovernment.moa.id.auth.modules.auth.dummy.service; + +import java.io.IOException; +import java.nio.file.FileVisitOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EAAFException; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egovernment.moa.id.auth.modules.auth.dummy.ConfigurationProperties; +import at.gv.egovernment.moa.logging.Logger; + +/** + * Service that holdes and selects dummy-identities for dummy-authentication. + * + * @author tlenz + * + */ +public class DummyIdentityService { + + @Autowired IConfiguration config; + + private List<Map<String, String>> availableIdentities = new ArrayList<>(); + + + private static ObjectMapper jsonMapper = new ObjectMapper(); + + static { + // initialize JSON Mapper + jsonMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true); + jsonMapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true); + jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); + jsonMapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); + jsonMapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY); + jsonMapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY); + + } + + + /** + * Get an identity randomly from available identities. + * + * @return Map of identity attributes + * @throws EAAFAuthenticationException In case of an empty identity store + */ + public Map<String, String> getIdentityRandomly() throws EAAFAuthenticationException { + if (availableIdentities.isEmpty()) { + throw new EAAFAuthenticationException("builder.08", new Object[] {"No Dummy-Identity available"}); + + } + + + + int num = (int) (Math.random() * 1000000) % availableIdentities.size(); + Logger.debug("Select element: " + num + " from dummy-identity store"); + return availableIdentities.get(num); + + } + + /** + * Get number of available identity sets. + * + * @return available dummy identities + */ + public int getNumberOfLoadedIdentitySets( ) { + return availableIdentities.size(); + + } + + + @PostConstruct + private void initialize() throws EAAFException { + try { + Logger.debug("Initializing Dummy-Identity authentication service ... "); + + //get all files from datastore + Set<Path> identityConfigFiles = getAllFilesFromIdentityStore(); + Logger.debug("Find #" + identityConfigFiles.size() + " files in identity-store. Starting identity extraction ... "); + + //extract identity informations + identityConfigFiles.stream() + .filter(el -> FilenameUtils.isExtension(el.getFileName().toString(), ConfigurationProperties.ALLOWED_FILE_TYPE)) + .forEach(el -> loadJson(el)); + + Logger.info("Dummy-Identity authentication service contains #" + availableIdentities.size() + " data-sets"); + + } catch (EAAFException e) { + handleError(e); + + } catch (IOException e) { + handleError(new EAAFException("config.05", + new Object[] {ConfigurationProperties.PROP_MODULE_IDENTITY_STORE_PATH}, e)); + + } + } + + + private void loadJson(Path file) { + try { + Logger.debug("Reading dummy-identity from file: " + file.getFileName() + " ... "); + Map<String, String> dummyEid = jsonMapper.readValue(file.toFile(), Map.class); + + // check minimum required attributes + ConfigurationProperties.MINIMUM_REQ_ATTRIBUTES.stream().forEach( + el -> { + if (!dummyEid.containsKey(el)) { + throw new RuntimeException("dummy-identity from file: " + file.getFileName() + " missing attribute: " + el); + + } + }); + + Logger.debug("Add dummy-identity from file: " + file.getFileName()); + availableIdentities.add(dummyEid); + + + } catch (Exception e) { + Logger.warn("Can NOT read dummy-identity from file: " + file.getFileName() + " Identity will be skipped", e); + + } + + } + + + private Set<Path> getAllFilesFromIdentityStore() throws IOException, EAAFConfigurationException { + String identityStorePath = config.getBasicConfiguration(ConfigurationProperties.PROP_MODULE_IDENTITY_STORE_PATH); + if (StringUtils.isEmpty(identityStorePath)) { + throw new EAAFConfigurationException("config.08", + new Object[] {ConfigurationProperties.PROP_MODULE_IDENTITY_STORE_PATH}); + + } + + String absIdentityStorePath = FileUtils.makeAbsoluteURL(identityStorePath, config.getConfigurationRootDirectory()); + if (absIdentityStorePath.startsWith("file:")) { + absIdentityStorePath = absIdentityStorePath.substring("file:".length()); + + } + + return Files.walk(Paths.get(absIdentityStorePath), FileVisitOption.FOLLOW_LINKS) + .filter(Files::isRegularFile) + .filter(Files::isReadable) + .collect(Collectors.toSet()); + + } + + + private void handleError(EAAFException e) throws EAAFException { + if (config.getBasicConfigurationBoolean(ConfigurationProperties.PROP_MODULE_ENABLED, false)) { + throw e; + + } else { + Logger.info("Dummy-Identity authentication is disabled. Ignore exception: " + e.getMessage()); + + } + + } + + +} diff --git a/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/task/InjectDummyIdentityInformationTask.java b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/task/InjectDummyIdentityInformationTask.java new file mode 100644 index 000000000..5eb441bc9 --- /dev/null +++ b/id/server/modules/moa-id-module-dummyAuth/src/main/java/at/gv/egovernment/moa/id/auth/modules/auth/dummy/task/InjectDummyIdentityInformationTask.java @@ -0,0 +1,140 @@ +/* + * Copyright 2021 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.auth.dummy.task; + +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionWrapper; +import at.gv.egovernment.moa.id.auth.modules.auth.dummy.service.DummyIdentityService; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +@Component("InjectDummyIdentityInformationTask") +public class InjectDummyIdentityInformationTask extends AbstractAuthServletTask { + + @Autowired + IConfiguration moaAuthConfig; + @Autowired + DummyIdentityService service; + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask#execute(at.gv. + * egovernment.moa.id.process.api.ExecutionContext, + * javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) + throws TaskExecutionException { + + try { + Logger.debug("Injecting user credentials for Dummy-Identity authentication ... "); + parseDemoValuesIntoMOASession(pendingReq); + + // set 'needConsent' to false, because user gives consent during authentication + pendingReq.setNeedUserConsent(false); + + // set 'authenticated' flag to true + pendingReq.setAuthenticated(true); + + // store MOASession into database + requestStoreage.storePendingRequest(pendingReq); + + } catch (final MOAIDException e) { + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } catch (final Exception e) { + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } + } + + /** + * @param pendingReq + * @param moaSession + * @throws MOAIDException + * @throws EAAFStorageException + * @throws EAAFAuthenticationException + */ + private void parseDemoValuesIntoMOASession(IRequest pendingReq) throws MOAIDException, EAAFStorageException, + EAAFAuthenticationException { + final AuthenticationSessionWrapper moaSession = pendingReq.getSessionData( + AuthenticationSessionWrapper.class); + moaSession.setForeigner(false); + moaSession.setQAALevel(PVPConstants.EIDAS_QAA_HIGH); + + final Map<String, String> rawIdentity = service.getIdentityRandomly(); + + // add attributes into session + for (final Entry<String, String> el : rawIdentity.entrySet()) { + moaSession.setGenericDataToSession(el.getKey(), el.getValue()); + Logger.debug("Add PVP-attribute " + el.getKey() + " into MOASession"); + + } + + // set BKU URL + if (rawIdentity.containsKey(PVPAttributeDefinitions.EID_CCS_URL_NAME)) { + moaSession.setBkuURL(rawIdentity.get(PVPAttributeDefinitions.EID_CCS_URL_NAME)); + + } else { + moaSession.setBkuURL("http://egiz.gv.at/dummy-authentication"); + + } + + // check if mandates are included + if (rawIdentity.containsKey(PVPAttributeDefinitions.MANDATE_TYPE_NAME) + || rawIdentity.containsKey(PVPAttributeDefinitions.MANDATE_TYPE_OID_NAME)) { + Logger.debug("Find Mandate-Attributes in E-ID response. Switch to mandate-mode ... "); + moaSession.setUseMandates(true); + + } else { + moaSession.setUseMandates(false); + + } + } + +} |