diff --git a/docker-compose/dependent-docker-compose.yml b/docker-compose/dependent-docker-compose.yml index 3e749e669..b3d462420 100644 --- a/docker-compose/dependent-docker-compose.yml +++ b/docker-compose/dependent-docker-compose.yml @@ -17,7 +17,7 @@ services: restart: always mock-identity-system: - image: 'mosipdev/mock-identity-system:develop' + image: 'mosipdev/mock-identity-system:release-0.10.x' user: root ports: - 8082:8082 diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index 754d7a6b6..2d438f128 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -10,7 +10,7 @@ services: - ./init.sql:/docker-entrypoint-initdb.d/init.sql mock-identity-system: - image: 'mosipdev/mock-identity-system:develop' + image: 'mosipdev/mock-identity-system:release-0.10.x' user: root ports: - 8082:8082 @@ -24,7 +24,7 @@ services: - database esignet: - image: 'mosipdev/esignet:develop' + image: 'mosipdev/esignet:release-1.5.x' user: root ports: - 8088:8088 @@ -42,9 +42,7 @@ services: - mock-identity-system esignet-ui: - build: - context: ../oidc-ui - dockerfile: Dockerfile + image: 'mosipdev/oidc-ui:release-1.5.x' user: root ports: - 3000:3000 diff --git a/docs/design/eSignet-overview.md b/docs/design/eSignet-overview.md new file mode 100644 index 000000000..421f6205d --- /dev/null +++ b/docs/design/eSignet-overview.md @@ -0,0 +1,6 @@ +# Overview + +eSignet offers a seamless and straightforward solution for incorporating an existing trusted identity database into the +digital realm via plugins. + +![esignet-architecture-overview.png](../esignet-architecture-overview.png) \ No newline at end of file diff --git a/docs/design/identity-assurance-flow.md b/docs/design/identity-assurance-flow.md new file mode 100644 index 000000000..d8741bae9 --- /dev/null +++ b/docs/design/identity-assurance-flow.md @@ -0,0 +1,45 @@ +# Overview + +A relying party could request for verified claims using the claims request parameter. eSignet pulls the existing claims +metadata on successful authentication of the user. If the existing claims metadata does not suffice the relying party request +then eSignet prompts the user to go through eKYC verification process. To handle eKYC verification process user will be +redirected to eSignet signup portal. On successful eKYC verification process, verified claim and its verification details +are stored in the integrated ID registry. As the verified claim and its metadata is stored, eSignet will be able to serve +the relying party's verified claims request. + +User must consent to go through the eKYC verification process. if the user denies to take the verification process, then +it is considered as consent rejection to share the requested verified claims with the relying party. + +If any one of the requested verified claim is mandatory, then user is prompted to go through eKYC verification process. +On confirmation, user is redirected to signup portal to carry out the verification process. If all the +requested verified claims are optional, no prompt is displayed. User is directly taken to the consent screen. +Option to choose eKYC verification process is supposed to be displayed in the consent screen in the later case(not implemented). + +# Changes required in eSignet + +* Authenticator interface: + * On successful authentication, integrated IDA system should return back claims metadata of an authenticated user. + * On KYC exchange, requested verified claims should be sent to the kyc_exchange method so the plugin should have all + the requested details to build the userinfo JWT with the requested verified claim details. + +* OIDC UI: + * After successful authentication, display requested claim availability & verification status to the user. So user can + take well-informed decision to agree or deny eKYC verification process. + * Authenticated user should be able to start a verification process in signup portal with the same authenticated context. + ID token based authentication of the user should be provisioned. + * If no claims are requested by the relying party, consent screen should be skipped. + * Logic to handle flawless resume of OIDC transaction after successful eKYC verification process. + +* Authorization Controller: + * oauth-details endpoint should support verified_claims in the current claims request parameter. + * consent-management should be modified to consider verified claims. + * id_token_hint request parameter part of the OIDC protocols 'authorize' call should be supported and should be be only + allowed for signup portal OIDC client ID. + * v3/authenticate endpoint should support new 'IDT' ACR and support ID token based authentication only when a cookie + exists with name equal to the 'sub' in the input ID token. Value of the matching cookie should have valid server nonce. + * New endpoint to fetch authenticated user's claim status in the integrated ID system. Mainly availability and verification status. + +# Sequence diagram: + +![identity-assurance-flow-drawio.png](../identity-assurance-flow-drawio.png) + diff --git a/docs/identity-assurance-flow-drawio.png b/docs/identity-assurance-flow-drawio.png new file mode 100644 index 000000000..c108ff28b Binary files /dev/null and b/docs/identity-assurance-flow-drawio.png differ diff --git a/esignet-core/pom.xml b/esignet-core/pom.xml index 9a27b8de7..4e06e2702 100644 --- a/esignet-core/pom.xml +++ b/esignet-core/pom.xml @@ -25,7 +25,7 @@ 2.15.0 2.15.0 2.15.0 - 1.2.0.2-SNAPSHOT + 1.2.1.0 3.27.0-GA 4.13.2 2.22.0 diff --git a/esignet-core/src/main/java/io/mosip/esignet/core/util/NoOpKeyBinderImpl.java b/esignet-core/src/main/java/io/mosip/esignet/core/util/NoOpKeyBinderImpl.java new file mode 100644 index 000000000..9fc026489 --- /dev/null +++ b/esignet-core/src/main/java/io/mosip/esignet/core/util/NoOpKeyBinderImpl.java @@ -0,0 +1,37 @@ +package io.mosip.esignet.core.util; + +import io.mosip.esignet.api.dto.AuthChallenge; +import io.mosip.esignet.api.dto.KeyBindingResult; +import io.mosip.esignet.api.dto.SendOtpResult; +import io.mosip.esignet.api.exception.KeyBindingException; +import io.mosip.esignet.api.exception.SendOtpException; +import io.mosip.esignet.api.spi.KeyBinder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static io.mosip.esignet.api.util.ErrorConstants.NOT_IMPLEMENTED; + +@ConditionalOnProperty(value = "mosip.esignet.integration.key-binder", havingValue = "NoOpKeyBinder") +@Component +@Slf4j +public class NoOpKeyBinderImpl implements KeyBinder { + + @Override + public SendOtpResult sendBindingOtp(String individualId, List otpChannels, Map requestHeaders) throws SendOtpException { + throw new SendOtpException(NOT_IMPLEMENTED); + } + + @Override + public KeyBindingResult doKeyBinding(String individualId, List challengeList, Map publicKeyJWK, String bindAuthFactorType, Map requestHeaders) throws KeyBindingException { + throw new KeyBindingException(NOT_IMPLEMENTED); + } + + @Override + public List getSupportedChallengeFormats(String authFactorType) { + return List.of(); + } +} diff --git a/esignet-service/README.md b/esignet-service/README.md index 0531ab4fc..c14821025 100644 --- a/esignet-service/README.md +++ b/esignet-service/README.md @@ -1,4 +1,4 @@ -## e-Signet Service +## eSignet Service * AuthorizationController - All the endpoints used by oidc-ui to begin the OIDC transaction, authenticate, take consent and generate auth-code. * ClientManagementController - Endpoints to create/update OIDC clients @@ -7,12 +7,10 @@ * OpenIdController - Endpoints specific to OIDC protocol like /userinfo and /.well-known/openid-configuration * SystemInfoController - Endpoints to get the pet public part of the keys managed in the keystore by keymanager. * KeyBindingController - Endpoints used by wallets to bind a key to an individual ID to support wallet local authentication. -* VCIController - Wallet initiated /credential endpoint returning just in time credential and /.well-known/openid-credential-issuer endpoint specific to [OpenID4VCI specification](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) -Note: VCI implementations currently only supports ldp_vc format with 'jwt' PoP. And we only issue scope based VC. -Both mock plugin and the MOSIP IDA plugin supports only scoped based VC issuance. +Note: VCI implementations are permanently moved to Inji-Certify. -## e-Signet Plugins +## eSignet Plugins 1. We have well-defined plugin interfaces in esignet-intergration-api. 2. Mock plugin implementations and the MOSIP specific plugin implementations are available. 3. Check the below URL for more details: @@ -25,54 +23,9 @@ Both mock plugin and the MOSIP IDA plugin supports only scoped based VC issuance ![](/docs/esignet-service-basic-interations.png) -## Local setup of e-Signet with mock plugins - -1. Create database mosip_esignet. -2. Run all the scripts under db_scripts/mosip_esignet/ddl folder. -3. Run the below insert statements in mosip_esignet database: - - > INSERT INTO KEY_POLICY_DEF(APP_ID,KEY_VALIDITY_DURATION,PRE_EXPIRE_DAYS,ACCESS_ALLOWED,IS_ACTIVE,CR_BY,CR_DTIMES) VALUES ('ROOT', 1095, 50, 'NA', true, 'mosipadmin', now()); - - > INSERT INTO KEY_POLICY_DEF(APP_ID,KEY_VALIDITY_DURATION,PRE_EXPIRE_DAYS,ACCESS_ALLOWED,IS_ACTIVE,CR_BY,CR_DTIMES) VALUES ('OIDC_SERVICE', 1095, 50, 'NA', true, 'mosipadmin', now()); - - > INSERT INTO KEY_POLICY_DEF(APP_ID,KEY_VALIDITY_DURATION,PRE_EXPIRE_DAYS,ACCESS_ALLOWED,IS_ACTIVE,CR_BY,CR_DTIMES) VALUES ('OIDC_PARTNER', 1095, 50, 'NA', true, 'mosipadmin', now()); - - > INSERT INTO KEY_POLICY_DEF(APP_ID,KEY_VALIDITY_DURATION,PRE_EXPIRE_DAYS,ACCESS_ALLOWED,IS_ACTIVE,CR_BY,CR_DTIMES) VALUES ('BINDING_SERVICE', 1095, 50, 'NA', true, 'mosipadmin', now()); - - > INSERT INTO KEY_POLICY_DEF(APP_ID,KEY_VALIDITY_DURATION,PRE_EXPIRE_DAYS,ACCESS_ALLOWED,IS_ACTIVE,CR_BY,CR_DTIMES) VALUES ('MOCK_BINDING_SERVICE', 1095, 50, 'NA', true, 'mosipadmin', now()); - -4. Build the plugin jar from below repo and add the built plugin jar as runtime dependency in esignet-service - - > https://github.com/mosip/esignet-mock-services/tree/master/mock-esignet-integration-impl - -5. Build the current esignet repository with the below command: - - > mvn clean install -Dgpg.skip=true -DskipTests=true - -6. Run the below command to start the esignet-service with mock plugin - - > java -jar -Dloader.path=mock-esignet-integration-impl.jar esignet-service.jar - -7. Once the service is up, swagger should be accessible with the below URL - - > http://localhost:8088/v1/esignet/swagger-ui.html - -8. Mock plugins connect to mock-identity-system, refer below document to start mock-identity-system in parallel - - > https://github.com/mosip/esignet-mock-services/tree/master/mock-identity-system#local-setup-of-mock-identity-system - -9. Also find the latest postman collection under "docs/postman-collections" folder with environment json - - Order of execution in postman script for OIDC flow is: - * Create identity - * Create OIDC client - * Authorize / OAuthdetails request - * Send OTP - * Authenticate user - * Authorization Code - * Get Tokens - * Get Userinfo +## Local setup of eSignet with mock plugins +Kindly check our docker compose setup files to run eSignet locally [here](../docker-compose) ## Caching details @@ -102,7 +55,7 @@ Linked transactions | userinfo | | | -Identity verification transaction +eKYC verification transaction | Endpoint | Cache | Evict | |----------------------------------------|------------------------------------------------------|------------------------------------------------------| @@ -110,12 +63,16 @@ Identity verification transaction | authenticate | authenticated (k: transactionId, v: OIDCTransaction) | preauth (k: transactionId, v: OIDCTransaction) | | claim-details(limited to 1 invocation) | authenticated (k: transactionId, v: OIDCTransaction) | | | prepare-signup-redirect | halted (k: transactionId, v: OIDCTransaction) | authenticated (k: transactionId, v: OIDCTransaction) | -| resume | authenticated (k: transactionId, v: OIDCTransaction) | halted (k: transactionId, v: OIDCTransaction) | +| complete-signup-redirect | authenticated (k: transactionId, v: OIDCTransaction) | halted (k: transactionId, v: OIDCTransaction) | | authCode | authcodegenerated (k: codeHash, v: OIDCTransaction) | authenticated (k: transactionId, v: OIDCTransaction) | | token | userinfo (k: accessTokenHash, v: OIDCTransaction) | authcodegenerated (k: codeHash, v: OIDCTransaction) | | userinfo | | | +## API document + +eSignet API documentation can be found [here](../docs/esignet-openapi.yaml) + ## Databases Refer to [SQL scripts](db_scripts/mosip_esignet). diff --git a/esignet-service/src/main/resources/application-default.properties b/esignet-service/src/main/resources/application-default.properties index e94c2da14..ed7004346 100644 --- a/esignet-service/src/main/resources/application-default.properties +++ b/esignet-service/src/main/resources/application-default.properties @@ -2,24 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -## Tomcat access logs -server.tomcat.accesslog.enabled=true -server.tomcat.accesslog.directory=/dev -server.tomcat.accesslog.prefix=stdout -server.tomcat.accesslog.buffered=false -server.tomcat.accesslog.suffix= -server.tomcat.accesslog.file-date-format= -server.tomcat.accesslog.pattern={"@timestamp":"%{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}t","level":"ACCESS","level_value":70000,"traceId":"%{X-B3-TraceId}i","statusCode":%s,"req.requestURI":"%U","bytesSent":%b,"timeTaken":%T,"appName":"${spring.application.name}","req.userAgent":"%{User-Agent}i","req.xForwardedFor":"%{X-Forwarded-For}i","req.referer":"%{Referer}i","req.method":"%m","req.remoteHost":"%a"} -server.tomcat.accesslog.className=io.mosip.kernel.core.logger.config.SleuthValve -#logging.level.org.springframework.web.client.RestTemplate=INFO -logging.level.io.mosip.esignet=INFO - -## Prometheus -management.endpoint.metrics.enabled=true -management.endpoints.web.exposure.include=* -management.endpoint.prometheus.enabled=true -management.metrics.export.prometheus.enabled=true - ## eSignet configurations mosip.esignet.auth-txn-id-length=10 mosip.esignet.supported-id-regex=\\S* @@ -416,4 +398,6 @@ mosip.esignet.ui.config.key-values={'sbi.env': '${mosip.esignet.authenticator.id 'auth.factor.kbi.field-details': ${mosip.esignet.authenticator.default.auth-factor.kbi.field-details}} ##-------------------------------------------- Default Integrations ----------------------------------------------------- + mosip.esignet.integration.audit-plugin=LoggerAuditService +mosip.esignet.integration.key-binder=NoOpKeyBinder \ No newline at end of file diff --git a/esignet-service/src/main/resources/application-local.properties b/esignet-service/src/main/resources/application-local.properties index 396d4674e..802a3a338 100644 --- a/esignet-service/src/main/resources/application-local.properties +++ b/esignet-service/src/main/resources/application-local.properties @@ -4,17 +4,7 @@ mosip.esignet.mock.domain.url=http://localhost:8082 -## Tomcat access logs -server.tomcat.accesslog.enabled=true -server.tomcat.accesslog.directory=/dev -server.tomcat.accesslog.prefix=stdout -server.tomcat.accesslog.buffered=false -server.tomcat.accesslog.suffix= -server.tomcat.accesslog.file-date-format= -server.tomcat.accesslog.pattern={"@timestamp":"%{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}t","level":"ACCESS","level_value":70000,"traceId":"%{X-B3-TraceId}i","statusCode":%s,"req.requestURI":"%U","bytesSent":%b,"timeTaken":%T,"appName":"${spring.application.name}","req.userAgent":"%{User-Agent}i","req.xForwardedFor":"%{X-Forwarded-For}i","req.referer":"%{Referer}i","req.method":"%m","req.remoteHost":"%a"} -server.tomcat.accesslog.className=io.mosip.kernel.core.logger.config.SleuthValve -#logging.level.org.springframework.web.client.RestTemplate=INFO -logging.level.io.mosip.esignet=INFO +logging.level.io.mosip.esignet=DEBUG ## eSignet configurations mosip.esignet.amr-acr-mapping-file-path=amr_acr_mapping.json @@ -399,4 +389,6 @@ mosip.esignet.ui.config.key-values={'sbi.env': '${mosip.esignet.authenticator.id 'auth.factor.kbi.field-details': ${mosip.esignet.authenticator.default.auth-factor.kbi.field-details}} ##-------------------------------------------- Default Integrations ----------------------------------------------------- + mosip.esignet.integration.audit-plugin=LoggerAuditService +mosip.esignet.integration.key-binder=NoOpKeyBinder diff --git a/esignet-service/src/main/resources/bootstrap.properties b/esignet-service/src/main/resources/bootstrap.properties index 0e1c09ca7..4077637b0 100644 --- a/esignet-service/src/main/resources/bootstrap.properties +++ b/esignet-service/src/main/resources/bootstrap.properties @@ -28,3 +28,21 @@ spring.messages.basename=messages spring.messages.encoding=UTF-8 spring.main.allow-bean-definition-overriding=true + +## Tomcat access logs +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.directory=/dev +server.tomcat.accesslog.prefix=stdout +server.tomcat.accesslog.buffered=false +server.tomcat.accesslog.suffix= +server.tomcat.accesslog.file-date-format= +server.tomcat.accesslog.pattern={"@timestamp":"%{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}t","level":"ACCESS","level_value":70000,"traceId":"%{X-B3-TraceId}i","statusCode":%s,"req.requestURI":"%U","bytesSent":%b,"timeTaken":%T,"appName":"${spring.application.name}","req.userAgent":"%{User-Agent}i","req.xForwardedFor":"%{X-Forwarded-For}i","req.referer":"%{Referer}i","req.method":"%m","req.remoteHost":"%a"} +server.tomcat.accesslog.className=io.mosip.kernel.core.logger.config.SleuthValve +#logging.level.org.springframework.web.client.RestTemplate=INFO +logging.level.io.mosip.esignet=INFO + +## Prometheus +management.endpoint.metrics.enabled=true +management.endpoints.web.exposure.include=* +management.endpoint.prometheus.enabled=true +management.metrics.export.prometheus.enabled=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9de96b60e..5439543a3 100644 --- a/pom.xml +++ b/pom.xml @@ -62,10 +62,6 @@ false - - danubetech-maven-public - https://repo.danubetech.com/repository/maven-public/ -