Skip to content

Commit

Permalink
feat(jans-fido2): generation assertion options without username
Browse files Browse the repository at this point in the history
Signed-off-by: Milton Ch <j.milton.chambi.m@gmail.com>
  • Loading branch information
Milton-Ch committed Jan 31, 2024
1 parent 06b1a7a commit c3fe0f3
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public interface AssertionService {
@Path("/options")
public Response authenticate(String content);

@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
@Path("/options/generate")
public Response generateAuthenticate(String content);

@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,66 @@ public ObjectNode options(JsonNode params) {
return optionsResponseNode;
}

public ObjectNode generateOptions(JsonNode params) {
log.debug("Generate assertion options: {}", params);

// Create result object
ObjectNode optionsResponseNode = dataMapperService.createObjectNode();

// Put userVerification
UserVerification userVerification = commonVerifiers.prepareUserVerification(params);
optionsResponseNode.put("userVerification", userVerification.name());

// Generate and put challenge
String challenge = challengeGenerator.getAssertionChallenge();
optionsResponseNode.put("challenge", challenge);
log.debug("Put challenge {}", challenge);

// Put RP
String documentDomain = commonVerifiers.verifyRpDomain(params);
log.debug("Put rpId {}", documentDomain);
optionsResponseNode.put("rpId", documentDomain);

// Put timeout
int timeout = commonVerifiers.verifyTimeout(params);
log.debug("Put timeout {}", timeout);
optionsResponseNode.put("timeout", timeout);

// Copy extensions
if (params.hasNonNull("extensions")) {
JsonNode extensions = params.get("extensions");

optionsResponseNode.set("extensions", extensions);
log.debug("Put extensions {}", extensions);
}

optionsResponseNode.put("status", "ok");

Fido2AuthenticationData entity = new Fido2AuthenticationData();
entity.setUsername(null);
entity.setChallenge(challenge);
entity.setDomain(documentDomain);
entity.setUserVerificationOption(userVerification);
entity.setStatus(Fido2AuthenticationStatus.pending);
entity.setApplicationId(documentDomain);

// Store original request
entity.setAssertionRequest(params.toString());

Fido2AuthenticationEntry authenticationEntity = authenticationPersistenceService.buildFido2AuthenticationEntry(entity, true);
if (params.hasNonNull("session_id")) {
authenticationEntity.setSessionStateId(params.get("session_id").asText());
}

// Set expiration
int unfinishedRequestExpiration = appConfiguration.getFido2Configuration().getUnfinishedRequestExpiration();
authenticationEntity.setExpiration(unfinishedRequestExpiration);

authenticationPersistenceService.save(authenticationEntity);

return optionsResponseNode;
}

public ObjectNode verify(JsonNode params) {
log.debug("authenticateResponse {}", params);

Expand Down Expand Up @@ -329,6 +389,7 @@ public ObjectNode verify(JsonNode params) {

finishResponseNode.put("status", "ok");
finishResponseNode.put("errorMessage", "");
finishResponseNode.put("username", registrationData.getUsername());

externalFido2InterceptionContext.addToContext(registrationEntry, authenticationEntity);
externalFido2InterceptionService.verifyAssertionFinish(finishResponseNode, externalFido2InterceptionContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,35 @@ public Response authenticate(String content) {
}
}

@POST
@Consumes({"application/json"})
@Produces({"application/json"})
@Path("/options/generate")
public Response generateAuthenticate(String content) {
try {
if (appConfiguration.getFido2Configuration() == null) {
throw errorResponseFactory.forbiddenException();
}

JsonNode params;
try {
params = dataMapperService.readTree(content);
} catch (IOException ex) {
throw errorResponseFactory.invalidRequest(ex.getMessage(), ex);
}
JsonNode result = assertionService.generateOptions(params);

ResponseBuilder builder = Response.ok().entity(result.toString());
return builder.build();

} catch (WebApplicationException e) {
throw e;
} catch (Exception e) {
log.error("Unknown Error: {}", e.getMessage(), e);
throw errorResponseFactory.unknownError(e.getMessage());
}
}

@POST
@Consumes({"application/json"})
@Produces({"application/json"})
Expand Down

0 comments on commit c3fe0f3

Please sign in to comment.