Search in sources :

Example 1 with WebAuthnManager

use of com.webauthn4j.WebAuthnManager 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);
}
Also used : RegistrationData(com.webauthn4j.data.RegistrationData) AuthInfo(com.tremolosecurity.proxy.auth.AuthInfo) ServerProperty(com.webauthn4j.server.ServerProperty) ValidationException(com.webauthn4j.validator.exception.ValidationException) OpenUnisonAuthenticator(com.tremolosecurity.proxy.auth.webauthn.OpenUnisonAuthenticator) WebAuthnUserData(com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData) WebAuthnManager(com.webauthn4j.WebAuthnManager) RegistrationRequest(com.webauthn4j.data.RegistrationRequest) AuthController(com.tremolosecurity.proxy.auth.AuthController) ValidationException(com.webauthn4j.validator.exception.ValidationException) ServletException(javax.servlet.ServletException) WebAuthnException(com.webauthn4j.util.exception.WebAuthnException) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ParseException(org.json.simple.parser.ParseException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) WebAuthnException(com.webauthn4j.util.exception.WebAuthnException) JSONObject(org.json.simple.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONParser(org.json.simple.parser.JSONParser) RegistrationParameters(com.webauthn4j.data.RegistrationParameters) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ObjectInputStream(java.io.ObjectInputStream) HashSet(java.util.HashSet)

Example 2 with WebAuthnManager

use of com.webauthn4j.WebAuthnManager 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;
    }
}
Also used : AuthenticationParameters(com.webauthn4j.data.AuthenticationParameters) ValidationException(com.webauthn4j.validator.exception.ValidationException) AuthenticationData(com.webauthn4j.data.AuthenticationData) Attribute(com.tremolosecurity.saml.Attribute) HashMap(java.util.HashMap) HttpServletRequest(javax.servlet.http.HttpServletRequest) UrlHolder(com.tremolosecurity.config.util.UrlHolder) ServletException(javax.servlet.ServletException) AuthenticationRequest(com.webauthn4j.data.AuthenticationRequest) AuthChainType(com.tremolosecurity.config.xml.AuthChainType) Authenticator(com.webauthn4j.authenticator.Authenticator) ServerProperty(com.webauthn4j.server.ServerProperty) HttpSession(javax.servlet.http.HttpSession) WebAuthnUserData(com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData) AuthMechType(com.tremolosecurity.config.xml.AuthMechType) WebAuthnManager(com.webauthn4j.WebAuthnManager) IOException(java.io.IOException) JSONObject(org.json.simple.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONParser(org.json.simple.parser.JSONParser) ParseException(org.json.simple.parser.ParseException) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ObjectInputStream(java.io.ObjectInputStream)

Example 3 with WebAuthnManager

use of com.webauthn4j.WebAuthnManager in project webauthn4j-spring-security by webauthn4j.

the class WebSecurityBeanConfig method webAuthnManager.

@Bean
public WebAuthnManager webAuthnManager(ObjectConverter objectConverter) {
    WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager(objectConverter);
    webAuthnManager.getAuthenticationDataValidator().setCrossOriginAllowed(true);
    return webAuthnManager;
}
Also used : WebAuthnManager(com.webauthn4j.WebAuthnManager) Bean(org.springframework.context.annotation.Bean)

Example 4 with WebAuthnManager

use of com.webauthn4j.WebAuthnManager in project webauthn4j by webauthn4j.

the class RegistrationContextValidatorSample method athenticationValidationSample.

public void athenticationValidationSample() {
    // Client properties
    byte[] credentialId = null;
    byte[] clientDataJSON = null;
    byte[] authenticatorData = 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);
    // please load authenticator object persisted in the registration process in your manner
    Authenticator authenticator = load(credentialId);
    List<byte[]> allowCredentials = null;
    boolean userVerificationRequired = true;
    AuthenticationRequest authenticationRequest = new AuthenticationRequest(credentialId, authenticatorData, clientDataJSON, signature);
    AuthenticationParameters authenticationParameters = new AuthenticationParameters(serverProperty, authenticator, allowCredentials, userVerificationRequired);
    WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager();
    AuthenticationData response = webAuthnManager.validate(authenticationRequest, authenticationParameters);
    // please update the counter of the authenticator record
    updateCounter(response.getCredentialId(), response.getAuthenticatorData().getSignCount());
}
Also used : Origin(com.webauthn4j.data.client.Origin) ServerProperty(com.webauthn4j.server.ServerProperty) WebAuthnManager(com.webauthn4j.WebAuthnManager) Authenticator(com.webauthn4j.authenticator.Authenticator) Challenge(com.webauthn4j.data.client.challenge.Challenge)

Example 5 with WebAuthnManager

use of com.webauthn4j.WebAuthnManager in project webauthn4j by webauthn4j.

the class RegistrationContextValidatorSample method registrationValidationSample.

public void registrationValidationSample() {
    // Client properties
    byte[] clientDataJSON = null;
    byte[] attestationObject = null;
    Set<String> transports = null;
    // Server properties
    Origin origin = null;
    String rpId = null;
    Challenge challenge = null;
    byte[] tokenBindingId = null;
    ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, tokenBindingId);
    List<PublicKeyCredentialParameters> pubKeyCredParams = null;
    boolean userVerificationRequired = false;
    RegistrationRequest registrationRequest = new RegistrationRequest(clientDataJSON, attestationObject, transports);
    RegistrationParameters registrationParameters = new RegistrationParameters(serverProperty, pubKeyCredParams, userVerificationRequired);
    // WebAuthnManager.createNonStrictWebAuthnManager() returns a WebAuthnManager instance
    // which doesn't validate an attestation statement. It is recommended configuration for most web application.
    // If you are building enterprise web application and need to validate the attestation statement, use the constructor of
    // RegistrationContextValidator and provide validators you like
    WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager();
    RegistrationData response = webAuthnManager.validate(registrationRequest, registrationParameters);
    // please persist Authenticator object, which will be used in the authentication process.
    Authenticator authenticator = new // You may create your own Authenticator implementation to save friendly authenticator name
    AuthenticatorImpl(response.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(), response.getAttestationObject().getAttestationStatement(), response.getAttestationObject().getAuthenticatorData().getSignCount());
    // please persist authenticator in your manner
    save(authenticator);
}
Also used : Origin(com.webauthn4j.data.client.Origin) ServerProperty(com.webauthn4j.server.ServerProperty) WebAuthnManager(com.webauthn4j.WebAuthnManager) Challenge(com.webauthn4j.data.client.challenge.Challenge) AuthenticatorImpl(com.webauthn4j.authenticator.AuthenticatorImpl) Authenticator(com.webauthn4j.authenticator.Authenticator)

Aggregations

WebAuthnManager (com.webauthn4j.WebAuthnManager)6 ServerProperty (com.webauthn4j.server.ServerProperty)5 Authenticator (com.webauthn4j.authenticator.Authenticator)3 Challenge (com.webauthn4j.data.client.challenge.Challenge)3 WebAuthnUserData (com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData)2 DataConversionException (com.webauthn4j.converter.exception.DataConversionException)2 Origin (com.webauthn4j.data.client.Origin)2 ValidationException (com.webauthn4j.validator.exception.ValidationException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 IOException (java.io.IOException)2 ObjectInputStream (java.io.ObjectInputStream)2 ServletException (javax.servlet.ServletException)2 JSONObject (org.json.simple.JSONObject)2 JSONParser (org.json.simple.parser.JSONParser)2 ParseException (org.json.simple.parser.ParseException)2 UrlHolder (com.tremolosecurity.config.util.UrlHolder)1 AuthChainType (com.tremolosecurity.config.xml.AuthChainType)1 AuthMechType (com.tremolosecurity.config.xml.AuthMechType)1 AuthController (com.tremolosecurity.proxy.auth.AuthController)1 AuthInfo (com.tremolosecurity.proxy.auth.AuthInfo)1