-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement phonenumber cert validation in obs
- Loading branch information
Showing
8 changed files
with
209 additions
and
60 deletions.
There are no files selected for viewing
45 changes: 23 additions & 22 deletions
45
obs/obs-rest-api/src/main/java/com/adorsys/webank/obs/resource/RegistrationResourceApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,23 @@ | ||
//package com.adorsys.webank.obs.resource; | ||
// | ||
//import com.adorsys.webank.obs.dto.RegistrationRequest; | ||
//import io.swagger.v3.oas.annotations.Operation; | ||
//import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
//import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
//import org.springframework.http.ResponseEntity; | ||
//import org.springframework.web.bind.annotation.*; | ||
// | ||
//@RestController | ||
//@RequestMapping("/api/registration") | ||
//public interface RegistrationResourceApi { | ||
// | ||
// @Operation(summary = "Register a new bank account", description = "Accepts a phone number and public key for registration") | ||
// @ApiResponses(value = { | ||
// @ApiResponse(responseCode = "201", description = "Registration successful"), | ||
// @ApiResponse(responseCode = "400", description = "Invalid input"), | ||
// @ApiResponse(responseCode = "500", description = "Internal server error") | ||
// }) | ||
// @PostMapping | ||
// ResponseEntity<String> registerAccount(@RequestBody RegistrationRequest registrationRequest); | ||
//} | ||
package com.adorsys.webank.obs.resource; | ||
|
||
import com.adorsys.webank.obs.dto.RegistrationRequest; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequestMapping("/api/registration") | ||
public interface RegistrationResourceApi { | ||
|
||
@Operation(summary = "Register a new bank account", description = "Accepts a phone number and public key for registration") | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "201", description = "Registration successful"), | ||
@ApiResponse(responseCode = "400", description = "Invalid input"), | ||
@ApiResponse(responseCode = "500", description = "Internal server error") | ||
}) | ||
@PostMapping | ||
ResponseEntity<String> registerAccount(@RequestHeader(HttpHeaders.AUTHORIZATION) String authorizationHeader, @RequestBody RegistrationRequest registrationRequest); | ||
} |
63 changes: 36 additions & 27 deletions
63
obs/obs-rest/src/main/java/com/adorsys/webank/obs/resource/RegistrationResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,36 @@ | ||
//package com.adorsys.webank.obs.resource; | ||
// | ||
//import com.adorsys.webank.obs.dto.RegistrationRequest; | ||
//import com.adorsys.webank.obs.service.RegistrationServiceApi; | ||
//import org.springframework.beans.factory.annotation.Autowired; | ||
//import org.springframework.http.ResponseEntity; | ||
//import org.springframework.http.HttpStatus; | ||
//import org.springframework.web.bind.annotation.*; | ||
// | ||
//@RestController | ||
//@RequestMapping("/api/registration") | ||
//public class RegistrationResource implements RegistrationResourceApi { | ||
// | ||
// @Autowired | ||
// private RegistrationServiceApi registrationService; | ||
// @Override | ||
// @PostMapping | ||
// public ResponseEntity<String> registerAccount(@RequestBody RegistrationRequest registrationRequest) { | ||
// try { | ||
// String result = registrationService.registerAccount(registrationRequest); | ||
// return ResponseEntity.status(HttpStatus.CREATED).body(result); | ||
// } catch (Exception e) { | ||
// // Log the exception (optional) | ||
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred while processing the request."); | ||
// } | ||
// } | ||
//} | ||
package com.adorsys.webank.obs.resource; | ||
|
||
import com.adorsys.webank.obs.dto.RegistrationRequest; | ||
import com.adorsys.webank.obs.service.RegistrationServiceApi; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequestMapping("/api/registration") | ||
public class RegistrationResource implements RegistrationResourceApi { | ||
|
||
@Autowired | ||
private RegistrationServiceApi registrationService; | ||
@Override | ||
@PostMapping | ||
public ResponseEntity<String> registerAccount(@RequestHeader(HttpHeaders.AUTHORIZATION) String authorizationHeader, @RequestBody RegistrationRequest registrationRequest) { | ||
try { | ||
String jwtToken = extractJwtFromHeader(authorizationHeader); | ||
String result = registrationService.registerAccount(registrationRequest, jwtToken); | ||
return ResponseEntity.status(HttpStatus.CREATED).body(result); | ||
} catch (Exception e) { | ||
// Log the exception (optional) | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred while processing the request."); | ||
} | ||
} | ||
|
||
private String extractJwtFromHeader(String authorizationHeader) { | ||
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) { | ||
throw new IllegalArgumentException("Authorization header must start with 'Bearer '"); | ||
} | ||
return authorizationHeader.substring(7); // Remove "Bearer " prefix | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
obs/obs-service-impl/src/main/java/com/adorsys/webank/obs/security/JwtCertValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package com.adorsys.webank.obs.security; | ||
|
||
import com.nimbusds.jose.*; | ||
import com.nimbusds.jose.crypto.*; | ||
import com.nimbusds.jose.jwk.*; | ||
import com.nimbusds.jwt.*; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class JwtCertValidator { | ||
private static final Logger logger = LoggerFactory.getLogger(JwtCertValidator.class); | ||
|
||
/** | ||
* Validates the JWT by extracting the phoneJwt from its header and verifying signatures. | ||
* | ||
* @param jwtToken The JWT token string to validate. | ||
* @return True if valid, false otherwise. | ||
*/ | ||
public static boolean validateJWT(String jwtToken) { | ||
try { | ||
// Parse the main JWT token coming from the frontend | ||
SignedJWT signedJWT = SignedJWT.parse(jwtToken); | ||
|
||
logger.info("jwt is : {}", jwtToken); | ||
|
||
// Extract "phoneNumberJwt" from the JWT header | ||
Object phoneJwtObj = signedJWT.getHeader().toJSONObject().get("phoneNumberJwt"); | ||
if (phoneJwtObj == null) { | ||
throw new IllegalArgumentException("Missing 'phoneNumberJwt' field in JWT header."); | ||
} | ||
|
||
// Parse phoneJwt as a separate JWT | ||
SignedJWT phoneJwtSigned = SignedJWT.parse(phoneJwtObj.toString()); | ||
|
||
logger.info("phonejwtsigned : {} ", phoneJwtSigned); | ||
|
||
// Extract JWK from phoneJwt header | ||
JWK rawJwk = phoneJwtSigned.getHeader().getJWK(); | ||
if (rawJwk == null) { | ||
throw new IllegalArgumentException("Missing JWK in phoneNumberJwt header."); | ||
} | ||
JWK jwk = JWK.parse(rawJwk.toJSONObject()); | ||
|
||
// Validate the JWK for phoneJwt | ||
if (!(jwk instanceof ECKey publicKeyPhone)) { | ||
throw new IllegalArgumentException("Invalid or missing ECKey in phoneNumberJwt."); | ||
} | ||
|
||
// Use the extracted key to verify the phoneJwt signature | ||
JWSVerifier phoneJwtVerifier = new ECDSAVerifier(publicKeyPhone); | ||
|
||
if (!phoneJwtSigned.verify(phoneJwtVerifier)) { | ||
logger.error("phoneNumberJwt signature validation failed."); | ||
return false; | ||
} | ||
|
||
// Extract JWK from the main signedJWT header | ||
JWK rawJwkMain = signedJWT.getHeader().getJWK(); | ||
if (rawJwkMain == null) { | ||
throw new IllegalArgumentException("Missing JWK in signedJWT header."); | ||
} | ||
JWK jwkMain = JWK.parse(rawJwkMain.toJSONObject()); | ||
|
||
// Validate the JWK for signedJWT | ||
if (!(jwkMain instanceof ECKey publicKeyMain)) { | ||
throw new IllegalArgumentException("Invalid or missing ECKey in signedJWT."); | ||
} | ||
|
||
// Use the extracted key to verify the main signedJWT signature | ||
JWSVerifier signedJWTVerifier = new ECDSAVerifier(publicKeyMain); | ||
|
||
if (!signedJWT.verify(signedJWTVerifier)) { | ||
logger.error("JWT signature validation failed."); | ||
return false; | ||
} | ||
|
||
logger.info("JWT validation successful."); | ||
return true; | ||
} catch (Exception e) { | ||
logger.error("Error during JWT validation: ", e); | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters