From 36b6d299caa301520191778e80420a834c5374ca Mon Sep 17 00:00:00 2001 From: pvsaidurga Date: Mon, 27 Jan 2025 11:42:35 +0530 Subject: [PATCH 1/2] [ES-2164] Added support for user info response type Signed-off-by: pvsaidurga --- .../esignet/services/OAuthServiceImpl.java | 15 ++++++-- .../esignet/services/OAuthServiceTest.java | 36 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java b/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java index d7c0b37bb..85ba2a850 100644 --- a/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java +++ b/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java @@ -42,7 +42,6 @@ import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.*; -import java.util.stream.Collectors; import static io.mosip.esignet.api.util.ErrorConstants.DATA_EXCHANGE_FAILED; import static io.mosip.esignet.core.constants.Constants.*; @@ -104,9 +103,18 @@ public TokenResponse getTokens(TokenRequest tokenRequest,boolean isV2) throws Es authenticateClient(tokenRequest, clientDetailDto,isV2); + Map additionalConfig= clientDetailDto.getAdditionalConfig(); + String userinfoResponsetype = null; + if (additionalConfig != null && additionalConfig.containsKey("user_info_response_type")) { + Object responseTypeValue = additionalConfig.get("user_info_response_type"); + if (responseTypeValue != null) { + userinfoResponsetype = (String) responseTypeValue; + } + } + boolean isTransactionVCScoped = isTransactionVCScoped(transaction); if(!isTransactionVCScoped) { //if transaction is not VC scoped, only then do KYC exchange - KycExchangeResult kycExchangeResult = doKycExchange(transaction); + KycExchangeResult kycExchangeResult = doKycExchange(transaction,userinfoResponsetype); transaction.setEncryptedKyc(kycExchangeResult.getEncryptedKyc()); auditWrapper.logAudit(Action.DO_KYC_EXCHANGE, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(transaction.getTransactionId(), transaction), null); } @@ -251,7 +259,7 @@ private TokenResponse getTokenResponse(OIDCTransaction transaction, boolean isTr return tokenResponse; } - private KycExchangeResult doKycExchange(OIDCTransaction transaction) { + private KycExchangeResult doKycExchange(OIDCTransaction transaction, String userinfoResponsetype) { KycExchangeResult kycExchangeResult; try { VerifiedKycExchangeDto kycExchangeDto = new VerifiedKycExchangeDto(); @@ -286,6 +294,7 @@ private KycExchangeResult doKycExchange(OIDCTransaction transaction) { } } kycExchangeDto.setAcceptedClaimDetails(acceptedClaimDetails); + kycExchangeDto.setUserInfoResponseType(userinfoResponsetype); if(transaction.isInternalAuthSuccess()) { log.info("Internal kyc exchange is invoked as the transaction is marked as internal auth success"); diff --git a/oidc-service-impl/src/test/java/io/mosip/esignet/services/OAuthServiceTest.java b/oidc-service-impl/src/test/java/io/mosip/esignet/services/OAuthServiceTest.java index f158ed4e9..9bc2ad30f 100644 --- a/oidc-service-impl/src/test/java/io/mosip/esignet/services/OAuthServiceTest.java +++ b/oidc-service-impl/src/test/java/io/mosip/esignet/services/OAuthServiceTest.java @@ -98,6 +98,9 @@ public void getTokens_withValidRequest_thenPass() throws KycExchangeException { oidcTransaction.setRedirectUri("https://test-redirect-uri/test-page"); oidcTransaction.setIndividualId("individual-id"); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); KycExchangeResult kycExchangeResult = new KycExchangeResult(); kycExchangeResult.setEncryptedKyc("encrypted-kyc"); @@ -137,6 +140,9 @@ public void getTokens_withValidRequestWithPKCE_thenPass() throws KycExchangeExce oidcTransaction.setProofKeyCodeExchange(ProofKeyCodeExchange.getInstance("KgFzotzIWt3ZMFusBrpCIyWTP-F9QJdtM4Qb8m3I-4Q", "S256")); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); KycExchangeResult kycExchangeResult = new KycExchangeResult(); kycExchangeResult.setEncryptedKyc("encrypted-kyc"); @@ -191,6 +197,9 @@ public void getTokens_withValidVerifiedClaimRequest_thenPass() throws KycExchang oidcTransaction.setRequestedClaimDetails(requestedClaimDetail); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); KycExchangeResult kycExchangeResult = new KycExchangeResult(); kycExchangeResult.setEncryptedKyc("encrypted-kyc"); @@ -248,6 +257,9 @@ public void getTokens_withListOfVerifiedClaimRequest_thenPass() throws KycExchan oidcTransaction.setRequestedClaimDetails(requestedClaimDetail); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); KycExchangeResult kycExchangeResult = new KycExchangeResult(); kycExchangeResult.setEncryptedKyc("encrypted-kyc"); @@ -288,6 +300,9 @@ public void getTokens_withInternalKycExchange_thenPass() { oidcTransaction.setProofKeyCodeExchange(ProofKeyCodeExchange.getInstance("KgFzotzIWt3ZMFusBrpCIyWTP-F9QJdtM4Qb8m3I-4Q", "S256")); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); Mockito.when(authorizationHelperService.getKeyHash(Mockito.anyString())).thenReturn("code-hash"); @@ -331,6 +346,9 @@ public void getTokens_withNullClientIdInRequest_thenPass() throws KycExchangeExc oidcTransaction.setRedirectUri("https://test-redirect-uri/test-page"); oidcTransaction.setIndividualId("individual-id"); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); KycExchangeResult kycExchangeResult = new KycExchangeResult(); kycExchangeResult.setEncryptedKyc("encrypted-kyc"); @@ -367,6 +385,9 @@ public void getTokens_withEmptyClientIdInRequest_thenPass() throws KycExchangeEx oidcTransaction.setRedirectUri("https://test-redirect-uri/test-page"); oidcTransaction.setIndividualId("individual-id"); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); KycExchangeResult kycExchangeResult = new KycExchangeResult(); kycExchangeResult.setEncryptedKyc("encrypted-kyc"); @@ -425,6 +446,9 @@ public void getTokens_withInvalidRedirectUri_thenFail() { } ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri1/**", "http://test-redirect-uri-2")); tokenRequest.setRedirect_uri("https://test-redirect-uri/test/test-page"); Mockito.when(clientManagementService.getClientDetails(Mockito.anyString())).thenReturn(clientDetail); @@ -482,6 +506,9 @@ public void getTokens_withInvalidAssertionType_thenFail() { Mockito.when(cacheUtilService.getAuthCodeTransaction(Mockito.anyString())).thenReturn(oidcTransaction); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); tokenRequest.setRedirect_uri("https://test-redirect-uri/test/test-page"); Mockito.when(clientManagementService.getClientDetails(Mockito.anyString())).thenReturn(clientDetail); @@ -516,6 +543,9 @@ public void getTokens_withFailedDataExchange_thenFail() throws KycExchangeExcept Mockito.when(cacheUtilService.getAuthCodeTransaction(Mockito.anyString())).thenReturn(oidcTransaction); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); tokenRequest.setRedirect_uri("https://test-redirect-uri/test/test-page"); Mockito.when(clientManagementService.getClientDetails(Mockito.anyString())).thenReturn(clientDetail); @@ -553,6 +583,9 @@ public void getTokens_dataExchangeRuntimeException_thenFail() throws KycExchange Mockito.when(cacheUtilService.getAuthCodeTransaction(Mockito.anyString())).thenReturn(oidcTransaction); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); tokenRequest.setRedirect_uri("https://test-redirect-uri/test/test-page"); Mockito.when(clientManagementService.getClientDetails(Mockito.anyString())).thenReturn(clientDetail); @@ -695,6 +728,9 @@ public void getTokens_withVCScopedTransaction_thenPass() throws KycExchangeExcep oidcTransaction.setProofKeyCodeExchange(ProofKeyCodeExchange.getInstance("KgFzotzIWt3ZMFusBrpCIyWTP-F9QJdtM4Qb8m3I-4Q", "S256")); ClientDetail clientDetail = new ClientDetail(); + Map userInfoResponseType= new HashMap<>(); + userInfoResponseType.put("user_info_response_type","JWS"); + clientDetail.setAdditionalConfig(userInfoResponseType); clientDetail.setRedirectUris(Arrays.asList("https://test-redirect-uri/**", "http://test-redirect-uri-2")); Mockito.when(authorizationHelperService.getKeyHash(Mockito.anyString())).thenReturn("code-hash"); From e38d78ec28ea914d4916120ff321fc522a83eee0 Mon Sep 17 00:00:00 2001 From: pvsaidurga Date: Tue, 28 Jan 2025 10:06:05 +0530 Subject: [PATCH 2/2] [ES-2164] Updated review comments Signed-off-by: pvsaidurga --- .../mosip/esignet/core/constants/Constants.java | 2 ++ .../io/mosip/esignet/core/dto/ClientDetail.java | 7 +++++++ .../mosip/esignet/services/OAuthServiceImpl.java | 15 ++++----------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/esignet-core/src/main/java/io/mosip/esignet/core/constants/Constants.java b/esignet-core/src/main/java/io/mosip/esignet/core/constants/Constants.java index b72d8a9f8..53223ff64 100644 --- a/esignet-core/src/main/java/io/mosip/esignet/core/constants/Constants.java +++ b/esignet-core/src/main/java/io/mosip/esignet/core/constants/Constants.java @@ -52,4 +52,6 @@ public class Constants { public static final String SERVER_NONCE_SEPARATOR = "~###~"; public static final String VERIFICATION_COMPLETE = "COMPLETED"; public static final String VERIFIED_CLAIMS = "verified_claims"; + + public static final String USERINFO_RESPONSE_TYPE = "userinfo_response_type"; } diff --git a/esignet-core/src/main/java/io/mosip/esignet/core/dto/ClientDetail.java b/esignet-core/src/main/java/io/mosip/esignet/core/dto/ClientDetail.java index 07264dcd0..4670f4738 100644 --- a/esignet-core/src/main/java/io/mosip/esignet/core/dto/ClientDetail.java +++ b/esignet-core/src/main/java/io/mosip/esignet/core/dto/ClientDetail.java @@ -28,4 +28,11 @@ public class ClientDetail implements Serializable { private List grantTypes; private List clientAuthMethods; private Map additionalConfig; + + public Object getAdditionalConfig(String keyName, Object defaultValue) { + if (additionalConfig == null) { + return defaultValue; + } + return additionalConfig.getOrDefault(keyName, defaultValue); + } } diff --git a/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java b/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java index 85ba2a850..2d15bec29 100644 --- a/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java +++ b/oidc-service-impl/src/main/java/io/mosip/esignet/services/OAuthServiceImpl.java @@ -103,18 +103,11 @@ public TokenResponse getTokens(TokenRequest tokenRequest,boolean isV2) throws Es authenticateClient(tokenRequest, clientDetailDto,isV2); - Map additionalConfig= clientDetailDto.getAdditionalConfig(); - String userinfoResponsetype = null; - if (additionalConfig != null && additionalConfig.containsKey("user_info_response_type")) { - Object responseTypeValue = additionalConfig.get("user_info_response_type"); - if (responseTypeValue != null) { - userinfoResponsetype = (String) responseTypeValue; - } - } + String userInfoResponseType = (String) clientDetailDto.getAdditionalConfig(USERINFO_RESPONSE_TYPE, "JWS"); boolean isTransactionVCScoped = isTransactionVCScoped(transaction); if(!isTransactionVCScoped) { //if transaction is not VC scoped, only then do KYC exchange - KycExchangeResult kycExchangeResult = doKycExchange(transaction,userinfoResponsetype); + KycExchangeResult kycExchangeResult = doKycExchange(transaction,userInfoResponseType); transaction.setEncryptedKyc(kycExchangeResult.getEncryptedKyc()); auditWrapper.logAudit(Action.DO_KYC_EXCHANGE, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(transaction.getTransactionId(), transaction), null); } @@ -259,7 +252,7 @@ private TokenResponse getTokenResponse(OIDCTransaction transaction, boolean isTr return tokenResponse; } - private KycExchangeResult doKycExchange(OIDCTransaction transaction, String userinfoResponsetype) { + private KycExchangeResult doKycExchange(OIDCTransaction transaction, String userInfoResponseType) { KycExchangeResult kycExchangeResult; try { VerifiedKycExchangeDto kycExchangeDto = new VerifiedKycExchangeDto(); @@ -294,7 +287,7 @@ private KycExchangeResult doKycExchange(OIDCTransaction transaction, String user } } kycExchangeDto.setAcceptedClaimDetails(acceptedClaimDetails); - kycExchangeDto.setUserInfoResponseType(userinfoResponsetype); + kycExchangeDto.setUserInfoResponseType(userInfoResponseType); if(transaction.isInternalAuthSuccess()) { log.info("Internal kyc exchange is invoked as the transaction is marked as internal auth success");