use of com.webauthn4j.converter.exception.DataConversionException in project OpenUnison by TremoloSecurity.
the class WebAuthnRegistration method storeCredential.
private void storeCredential(HttpFilterRequest request) throws ParseException, IOException, ClassNotFoundException, ServletException, Exception {
byte[] requestBytes = (byte[]) request.getAttribute(ProxySys.MSG_BODY);
String requestString = new String(requestBytes, StandardCharsets.UTF_8);
JSONObject root = (JSONObject) new JSONParser().parse(requestString);
if (root.get("label") == null || ((String) root.get("label")).isEmpty()) {
throw new WebAuthnException("Label required");
}
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getUrlDecoder().decode((String) root.get("serverProperty")));
ObjectInputStream ois = new ObjectInputStream(bais);
ServerProperty serverProperty = (ServerProperty) ois.readObject();
byte[] attestationObject = Base64.getUrlDecoder().decode((String) root.get("attestationObject"));
byte[] clientDataJSON = Base64.getUrlDecoder().decode((String) root.get("clientDataJSON"));
String clientExtensionJSON = (String) root.get("clientExtResults");
Set<String> transports = new HashSet<String>();
// expectations
boolean userVerificationRequired = false;
boolean userPresenceRequired = true;
RegistrationRequest registrationRequest = new RegistrationRequest(attestationObject, clientDataJSON, clientExtensionJSON, transports);
RegistrationParameters registrationParameters = new RegistrationParameters(serverProperty, userVerificationRequired, userPresenceRequired);
RegistrationData registrationData;
WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager();
try {
registrationData = webAuthnManager.parse(registrationRequest);
} catch (DataConversionException e) {
// If you would like to handle WebAuthn data structure parse error, please catch DataConversionException
throw e;
}
try {
webAuthnManager.validate(registrationData, registrationParameters);
} catch (ValidationException e) {
// If you would like to handle WebAuthn data validation error, please catch ValidationException
throw e;
}
OpenUnisonAuthenticator authenticator = new OpenUnisonAuthenticator((String) root.get("label"), registrationData.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(), registrationData.getAttestationObject().getAttestationStatement(), registrationData.getAttestationObject().getAuthenticatorData().getSignCount());
AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
WebAuthnUserData webAuthnUserData = WebAuthnUtils.lookupWebAuthnUserData(userData, this.challengeStoreAttribute, this.encryptionKeyName);
if (webAuthnUserData == null) {
throw new Exception("No webauthn user data, should not happen");
}
for (OpenUnisonAuthenticator auth : webAuthnUserData.getAuthenticators()) {
if (auth.getLabel().equals(authenticator.getLabel())) {
throw new WebAuthnException("Label already exists, choose another label");
}
}
webAuthnUserData.getAuthenticators().add(authenticator);
WebAuthnUtils.storeWebAuthnUserData(webAuthnUserData, encryptionKeyName, userData, workflowName, uidAttributeName, challengeStoreAttribute);
}
use of com.webauthn4j.converter.exception.DataConversionException in project OpenUnison by TremoloSecurity.
the class WebAuthn method doPost.
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response, AuthStep as) throws IOException, ServletException {
if (request.getParameter("webauthnResponse") != null) {
AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
// SharedSession.getSharedSession().getSession(req.getSession().getId());
HttpSession session = ((HttpServletRequest) request).getSession();
UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
String urlChain = holder.getUrl().getAuthChain();
AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
AuthMechType amt = act.getAuthMech().get(as.getId());
HashMap<String, Attribute> authParams = (HashMap<String, Attribute>) session.getAttribute(ProxyConstants.AUTH_MECH_PARAMS);
ByteArrayInputStream bais = new ByteArrayInputStream(Base64UrlUtil.decode((String) request.getParameter("serverProperty")));
ObjectInputStream ois = new ObjectInputStream(bais);
ServerProperty serverProperty = null;
try {
serverProperty = (ServerProperty) ois.readObject();
} catch (ClassNotFoundException | IOException e) {
throw new ServletException(e);
}
String attributeName = authParams.get("attribute").getValues().get(0);
String encryptionKeyName = authParams.get("encryptionKeyName").getValues().get(0);
Authenticator auth = null;
if (userData.getAttribs().get(attributeName) == null) {
StringBuilder sb = new StringBuilder();
sb.append("User '").append(userData.getUserDN()).append("' does not have attribute '").append(attributeName).append("'");
logger.warn(sb.toString());
as.setExecuted(true);
as.setSuccess(false);
holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
return;
}
WebAuthnUserData webauthnUser = WebAuthnUtils.lookupWebAuthnUserData(userData, attributeName, encryptionKeyName);
if (webauthnUser == null) {
throw new ServletException("No webauthn user data, can not happen");
}
JSONObject webauthnResp = null;
try {
webauthnResp = (JSONObject) new JSONParser().parse(request.getParameter("webauthnResponse"));
} catch (ParseException e) {
throw new ServletException("could not parse webauthn response", e);
}
byte[] credentialId = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("credential_id"));
byte[] userHandle = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("userHandle"));
;
byte[] authenticatorData = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("authenticatorData"));
byte[] clientDataJSON = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("clientDataJSON"));
String clientExtensionJSON = (String) webauthnResp.get("clientExtResults");
byte[] signature = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("signature"));
if (!Arrays.equals(userHandle, webauthnUser.getId())) {
StringBuilder sb = new StringBuilder();
sb.append("User '").append(userData.getUserDN()).append("' credential not owned by the client");
logger.warn(sb.toString());
as.setExecuted(true);
as.setSuccess(false);
holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
return;
}
auth = null;
for (Authenticator checkUser : webauthnUser.getAuthenticators()) {
if (Arrays.equals(checkUser.getAttestedCredentialData().getCredentialId(), credentialId)) {
auth = checkUser;
}
}
if (auth == null) {
StringBuilder sb = new StringBuilder();
sb.append("User '").append(userData.getUserDN()).append("' does not have a credential associated with '").append((String) webauthnResp.get("credential_id")).append("'");
logger.warn(sb.toString());
as.setExecuted(true);
as.setSuccess(false);
holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
return;
}
AuthenticationRequest authenticationRequest = new AuthenticationRequest(credentialId, userHandle, authenticatorData, clientDataJSON, clientExtensionJSON, signature);
AuthenticationParameters authenticationParameters = new AuthenticationParameters(serverProperty, auth, null, false, true);
WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager();
AuthenticationData authenticationData;
try {
authenticationData = webAuthnManager.parse(authenticationRequest);
} catch (DataConversionException e) {
StringBuilder sb = new StringBuilder();
sb.append("User '").append(userData.getUserDN()).append("' could not parse authentication data with credential '").append((String) webauthnResp.get("credential_id")).append("'");
logger.warn(sb.toString(), e);
as.setExecuted(true);
as.setSuccess(false);
holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
return;
}
try {
webAuthnManager.validate(authenticationData, authenticationParameters);
} catch (ValidationException e) {
StringBuilder sb = new StringBuilder();
sb.append("User '").append(userData.getUserDN()).append("' could not validate authentication data with credential '").append((String) webauthnResp.get("credential_id")).append("'");
logger.warn(sb.toString(), e);
as.setExecuted(true);
as.setSuccess(false);
holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
return;
}
as.setExecuted(true);
as.setSuccess(true);
holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
} else {
// redirect the user to the correct URL
AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
// SharedSession.getSharedSession().getSession(req.getSession().getId());
HttpSession session = ((HttpServletRequest) request).getSession();
UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
String urlChain = holder.getUrl().getAuthChain();
AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
AuthMechType amt = act.getAuthMech().get(as.getId());
response.sendRedirect(holder.getConfig().getAuthMechs().get(amt.getName()).getUri());
return;
}
}
use of com.webauthn4j.converter.exception.DataConversionException in project webauthn4j-spring-security by webauthn4j.
the class FidoServerAttestationOptionsEndpointFilter method processRequest.
@Override
protected ServerResponse processRequest(HttpServletRequest request) {
InputStream inputStream;
try {
inputStream = request.getInputStream();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
try {
ServerPublicKeyCredentialCreationOptionsRequest serverRequest = objectConverter.getJsonConverter().readValue(inputStream, ServerPublicKeyCredentialCreationOptionsRequest.class);
String username = serverRequest.getUsername();
String displayName = serverRequest.getDisplayName();
Challenge challenge = serverEndpointFilterUtil.encodeUsername(new DefaultChallenge(), username);
challengeRepository.saveChallenge(challenge, request);
// TODO: UsernamePasswordAuthenticationToken should not be used here in this way
AttestationOptions attestationOptions = optionsProvider.getAttestationOptions(request, new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList()));
String userHandle;
if (attestationOptions.getUser() == null) {
userHandle = Base64UrlUtil.encodeToString(generateUserHandle());
} else {
userHandle = Base64UrlUtil.encodeToString(attestationOptions.getUser().getId());
}
ServerPublicKeyCredentialUserEntity user = new ServerPublicKeyCredentialUserEntity(userHandle, username, displayName);
List<ServerPublicKeyCredentialDescriptor> credentials = attestationOptions.getExcludeCredentials().stream().map(credential -> new ServerPublicKeyCredentialDescriptor(credential.getType(), Base64UrlUtil.encodeToString(credential.getId()), credential.getTransports())).collect(Collectors.toList());
AuthenticationExtensionsClientInputs<RegistrationExtensionClientInput> authenticationExtensionsClientInputs;
if (serverRequest.getExtensions() != null) {
authenticationExtensionsClientInputs = serverRequest.getExtensions();
} else {
authenticationExtensionsClientInputs = attestationOptions.getExtensions();
}
return new ServerPublicKeyCredentialCreationOptionsResponse(attestationOptions.getRp(), user, Base64UrlUtil.encodeToString(attestationOptions.getChallenge().getValue()), attestationOptions.getPubKeyCredParams(), attestationOptions.getTimeout(), credentials, serverRequest.getAuthenticatorSelection(), serverRequest.getAttestation(), authenticationExtensionsClientInputs);
} catch (DataConversionException e) {
throw new com.webauthn4j.springframework.security.exception.DataConversionException("Failed to convert data", e);
}
}
use of com.webauthn4j.converter.exception.DataConversionException in project webauthn4j-spring-security by webauthn4j.
the class FidoServerAttestationResultEndpointFilter method processRequest.
@Override
protected ServerResponse processRequest(HttpServletRequest request) {
InputStream inputStream;
try {
inputStream = request.getInputStream();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
try {
ServerPublicKeyCredential<ServerAuthenticatorAttestationResponse> credential = this.objectConverter.getJsonConverter().readValue(inputStream, credentialTypeRef);
serverPublicKeyCredentialValidator.validate(credential);
ServerAuthenticatorAttestationResponse response = credential.getResponse();
CollectedClientData collectedClientData = collectedClientDataConverter.convert(response.getClientDataJSON());
AttestationObject attestationObject = attestationObjectConverter.convert(response.getAttestationObject());
Set<String> transports = Collections.emptySet();
webAuthnRegistrationRequestValidator.validate(request, response.getClientDataJSON(), response.getAttestationObject(), transports, credential.getClientExtensionResults());
String loginUsername = serverEndpointFilterUtil.decodeUsername(collectedClientData.getChallenge());
try {
userDetailsService.loadUserByUsername(loginUsername);
} catch (UsernameNotFoundException e) {
usernameNotFoundHandler.onUsernameNotFound(loginUsername);
}
UserDetails userDetails = userDetailsService.loadUserByUsername(loginUsername);
WebAuthnAuthenticatorImpl webAuthnAuthenticator = new WebAuthnAuthenticatorImpl("Authenticator", loginUsername, attestationObject.getAuthenticatorData().getAttestedCredentialData(), attestationObject.getAttestationStatement(), attestationObject.getAuthenticatorData().getSignCount());
webAuthnAuthenticatorManager.createAuthenticator(webAuthnAuthenticator);
return new AttestationResultSuccessResponse();
} catch (DataConversionException e) {
throw new com.webauthn4j.springframework.security.exception.DataConversionException("Failed to convert data", e);
}
}
use of com.webauthn4j.converter.exception.DataConversionException in project webauthn4j by webauthn4j.
the class WebAuthnManagerSample method authenticationValidationSample.
public void authenticationValidationSample() {
// Client properties
byte[] credentialId = null;
byte[] userHandle = null;
byte[] authenticatorData = null;
byte[] clientDataJSON = null;
String clientExtensionJSON = null;
byte[] signature = null;
// Server properties
Origin origin = null;
String rpId = null;
Challenge challenge = null;
byte[] tokenBindingId = null;
ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, tokenBindingId);
// expectations
List<byte[]> allowCredentials = null;
boolean userVerificationRequired = true;
boolean userPresenceRequired = true;
List<String> expectedExtensionIds = Collections.emptyList();
// please load authenticator object persisted in the registration process in your manner
Authenticator authenticator = load(credentialId);
AuthenticationRequest authenticationRequest = new AuthenticationRequest(credentialId, userHandle, authenticatorData, clientDataJSON, clientExtensionJSON, signature);
AuthenticationParameters authenticationParameters = new AuthenticationParameters(serverProperty, authenticator, allowCredentials, userVerificationRequired, userPresenceRequired);
AuthenticationData authenticationData;
try {
authenticationData = webAuthnManager.parse(authenticationRequest);
} catch (DataConversionException e) {
// If you would like to handle WebAuthn data structure parse error, please catch DataConversionException
throw e;
}
try {
webAuthnManager.validate(authenticationData, authenticationParameters);
} catch (ValidationException e) {
// If you would like to handle WebAuthn data validation error, please catch ValidationException
throw e;
}
// please update the counter of the authenticator record
updateCounter(authenticationData.getCredentialId(), authenticationData.getAuthenticatorData().getSignCount());
}
Aggregations