Search in sources :

Example 1 with AuthenticatedPrincipal

use of com.disney.http.auth.server.AuthenticatedPrincipal in project groovity by disney.

the class BasicVerifierImpl method doVerifyInternal.

@Override
protected VerifierResult doVerifyInternal(ServerAuthorizationRequest request) {
    VerifierResult result = new VerifierResult();
    List<String> basicAuth = request.getHeaders(AUTHORIZATION_HEADER);
    if (basicAuth == null || basicAuth.isEmpty()) {
        challenge(result, ERROR_MISSING_CREDENTIALS);
        return result;
    }
    BasicAuthorization auth;
    try {
        auth = new BasicAuthorization(basicAuth.get(0));
    } catch (Exception e) {
        challenge(result, e.getMessage());
        return result;
    }
    for (int i = 0; i < passwordCheckers.size(); i++) {
        PasswordChecker checker = passwordCheckers.get(i);
        if (checker.check(auth.getUsername(), auth.getPassword())) {
            result.setAuthenticated(true);
            result.setPrincipal(new AuthenticatedPrincipal(auth.getUsername()));
            return result;
        }
    }
    challenge(result, ERROR_UNKNOWN_CREDENTIALS);
    return result;
}
Also used : VerifierResult(com.disney.http.auth.server.VerifierResult) BasicAuthorization(com.disney.http.auth.BasicAuthorization) AuthenticatedPrincipal(com.disney.http.auth.server.AuthenticatedPrincipal)

Example 2 with AuthenticatedPrincipal

use of com.disney.http.auth.server.AuthenticatedPrincipal in project groovity by disney.

the class DigestVerifierImpl method doVerifyInternal.

@Override
protected VerifierResult doVerifyInternal(ServerAuthorizationRequest request) throws NoSuchAlgorithmException, IOException {
    VerifierResult result = new VerifierResult();
    List<String> headers = request.getHeaders(AUTHORIZATION_HEADER);
    String authHeader = null;
    for (String header : headers) {
        if (header.startsWith(DIGEST)) {
            authHeader = header;
            break;
        }
    }
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    if (authHeader == null) {
        challenge(request, md5, result, ERROR_MISSING_CREDENTIALS, false);
        return result;
    }
    DigestAuthorization authd;
    try {
        authd = new DigestAuthorization(authHeader);
    } catch (Exception e) {
        challenge(request, md5, result, e.getMessage(), false);
        return result;
    }
    // validate URI
    if (!request.getURI().equals(authd.getUri())) {
        challenge(request, md5, result, ERROR_INCORRECT_URI, false);
        return result;
    }
    String nonce = authd.getNonce();
    byte[] nonceBytes = DatatypeConverter.parseBase64Binary(nonce);
    // validate timestamp
    long timestamp = toLong(nonceBytes);
    // validate nonce
    if (!nonce.equals(makeNonce(md5, timestamp))) {
        challenge(request, md5, result, ERROR_INVALID_NONCE, false);
        return result;
    }
    // validate digest
    byte[] ha2 = DatatypeConverter.printHexBinary(md5.digest((request.getMethod() + ":" + authd.getUri()).getBytes("UTF-8"))).toLowerCase().getBytes();
    for (int i = 0; i < passwordDigesters.size(); i++) {
        PasswordDigester digester = passwordDigesters.get(i);
        byte[] ha1 = digester.digest(authd.getUsername(), getRealm());
        if (ha1 != null) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(200);
            baos.write(DatatypeConverter.printHexBinary(ha1).toLowerCase().getBytes());
            baos.write((byte) ':');
            baos.write(nonce.getBytes());
            baos.write((byte) ':');
            if ("auth".equals(authd.getQop())) {
                baos.write(authd.getNonceCount().getBytes());
                baos.write((byte) ':');
                baos.write(authd.getCnonce().getBytes("UTF-8"));
                baos.write((byte) ':');
                baos.write(authd.getQop().getBytes());
                baos.write((byte) ':');
            }
            byte[] rd = baos.toByteArray();
            md5.reset();
            md5.update(rd);
            md5.update(ha2);
            byte[] digestVal = md5.digest();
            if (Arrays.equals(digestVal, authd.getDigest())) {
                if ("auth".equals(authd.getQop())) {
                    md5.reset();
                    md5.update(rd);
                    md5.update(DatatypeConverter.printHexBinary(md5.digest((":" + authd.getUri()).getBytes("UTF-8"))).toLowerCase().getBytes());
                    byte[] rspAuth = md5.digest();
                    result.setAuthenticationInfo("qop=\"" + authd.getQop() + "\",cnonce=\"" + authd.getCnonce() + "\",nc=" + authd.getNonceCount() + ",rspauth=\"" + DatatypeConverter.printHexBinary(rspAuth).toLowerCase() + "\"");
                }
                if ((System.currentTimeMillis() - timestamp) > maxNonceAge) {
                    challenge(request, md5, result, ERROR_STALE_NONCE, true);
                } else {
                    result.setAuthenticated(true);
                    result.setPrincipal(new AuthenticatedPrincipal(authd.getUsername()));
                }
                return result;
            }
        }
    }
    challenge(request, md5, result, ERROR_UNKNOWN_CREDENTIALS, false);
    return result;
}
Also used : DigestAuthorization(com.disney.http.auth.DigestAuthorization) VerifierResult(com.disney.http.auth.server.VerifierResult) ByteArrayOutputStream(java.io.ByteArrayOutputStream) MessageDigest(java.security.MessageDigest) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AuthenticatedPrincipal(com.disney.http.auth.server.AuthenticatedPrincipal)

Example 3 with AuthenticatedPrincipal

use of com.disney.http.auth.server.AuthenticatedPrincipal in project groovity by disney.

the class SignatureVerifierImpl method doVerifyInternal.

/**
 * Given a request and response, analyze the request Authorization header and
 * look up the appropriate key in the keystore; if the
 * header is missing, incomplete or invalid, will send a 401 error on the response
 * with WWW-Authenticate header and return null.
 *
 * If the request contains a Digest header, the returned HttpServletRequest
 * will wrap the original with one that will lazily verify the request body.
 * Consumers should replace the original ServletRequest with the returned one
 * for further processing, and be prepared for the possible VerificationException
 *
 * @param request
 * @throws IOException
 * @throws GeneralSecurityException
 */
protected VerifierResult doVerifyInternal(ServerAuthorizationRequest request) throws Exception {
    VerifierResult result = new VerifierResult();
    List<String> authHeader = request.getHeaders(AUTHORIZATION_HEADER);
    if (authHeader == null || authHeader.isEmpty() || !authHeader.get(0).startsWith(SIGNATURE_HEADER)) {
        authHeader = request.getHeaders(SIGNATURE_HEADER);
    }
    // System.out.println("Received auth header "+authHeader);
    if (authHeader == null || authHeader.isEmpty()) {
        challenge(result, ERROR_MISSING_SIGNATURE);
        return result;
    }
    // this will throw an exception if the auth header is not properly formatted
    SignatureAuthorization authSig;
    try {
        authSig = new SignatureAuthorization(authHeader.get(0));
    } catch (Exception e) {
        challenge(result, e.getMessage());
        return result;
    }
    // now validate that the authSig was signed with all the required headers
    for (String required : requiredHeaders) {
        if (!authSig.getHeaders().contains(required.toLowerCase())) {
            if (required.toLowerCase().equals("date") && authSig.getHeaders().contains("x-date")) {
                // allow x-date to substitute for date
                continue;
            }
            challenge(result, MessageFormat.format(ERROR_MISSING_HEADER_FORMAT, required));
            return result;
        }
    }
    List<String> reqDateStr = request.getHeaders("x-date");
    if (reqDateStr == null || reqDateStr.isEmpty()) {
        reqDateStr = request.getHeaders("date");
    }
    // now validate the date is in range, use x-date if provided (for ajax support)
    long reqDate = -1;
    if (reqDateStr != null && !reqDateStr.isEmpty()) {
        String rd = reqDateStr.get(0);
        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
        try {
            reqDate = dateFormat.parse(rd).getTime();
        } catch (ParseException e) {
            dateFormat = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss zzz");
            try {
                reqDate = dateFormat.parse(rd).getTime();
            } catch (ParseException e1) {
                dateFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy");
                reqDate = dateFormat.parse(rd).getTime();
            }
        }
    }
    if ((System.currentTimeMillis() - reqDate) > maxDateDrift) {
        challenge(result, ERROR_INVALID_DATE);
        return result;
    }
    // now lookup the key
    String errorFormat = ERROR_UNKOWN_KEY_ID_FORMAT;
    Key[] keys = null;
    for (KeyChain keyChain : keyChains) {
        if (keyChain.containsKey(authSig.getKeyId())) {
            if (authSig.getAlgorithm().startsWith("hmac")) {
                try {
                    keys = keyChain.getSecretKeys(authSig.getKeyId());
                } catch (UnrecoverableKeyException e) {
                    errorFormat = ERROR_EXPECTED_HMAC_FORMAT;
                }
            } else {
                try {
                    keys = keyChain.getPublicKeys(authSig.getKeyId());
                } catch (UnrecoverableKeyException e) {
                    errorFormat = ERROR_EXPECTED_RSA_FORMAT;
                }
            }
        }
    }
    if (keys == null || keys.length == 0) {
        challenge(result, MessageFormat.format(errorFormat, authSig.getKeyId()));
        return result;
    }
    String errorMessage = null;
    for (Key key : keys) {
        // validate key algorithm is appropriate
        if (key.getAlgorithm().equals("RSA")) {
            if (!authSig.getAlgorithm().startsWith("rsa")) {
                errorMessage = MessageFormat.format(ERROR_EXPECTED_HMAC_FORMAT, authSig.getKeyId());
                continue;
            }
        }
        if (key.getAlgorithm().startsWith("Hmac")) {
            if (!authSig.getAlgorithm().startsWith("hmac")) {
                errorMessage = MessageFormat.format(ERROR_EXPECTED_RSA_FORMAT, authSig.getKeyId());
                continue;
            }
        }
        // now generate the signature to compare
        String toSign = authSig.generateSigningString(request);
        // System.out.println("Signing string is "+toSign);
        if (verifyMessage(key, toSign, authSig.getSignature(), authSig.getAlgorithm())) {
            result.setAuthenticated(true);
            result.setPrincipal(new AuthenticatedPrincipal(authSig.getKeyId()));
            return result;
        } else {
            errorMessage = ERROR_VERIFICATION_FAILED;
        }
    }
    challenge(result, errorMessage);
    return result;
}
Also used : KeyChain(com.disney.http.auth.keychain.KeyChain) SignatureException(java.security.SignatureException) IOException(java.io.IOException) GeneralSecurityException(java.security.GeneralSecurityException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) InvalidKeyException(java.security.InvalidKeyException) ParseException(java.text.ParseException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AuthenticatedPrincipal(com.disney.http.auth.server.AuthenticatedPrincipal) VerifierResult(com.disney.http.auth.server.VerifierResult) UnrecoverableKeyException(java.security.UnrecoverableKeyException) SignatureAuthorization(com.disney.http.auth.SignatureAuthorization) ParseException(java.text.ParseException) SimpleDateFormat(java.text.SimpleDateFormat) PublicKey(java.security.PublicKey) Key(java.security.Key)

Aggregations

AuthenticatedPrincipal (com.disney.http.auth.server.AuthenticatedPrincipal)3 VerifierResult (com.disney.http.auth.server.VerifierResult)3 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 BasicAuthorization (com.disney.http.auth.BasicAuthorization)1 DigestAuthorization (com.disney.http.auth.DigestAuthorization)1 SignatureAuthorization (com.disney.http.auth.SignatureAuthorization)1 KeyChain (com.disney.http.auth.keychain.KeyChain)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 GeneralSecurityException (java.security.GeneralSecurityException)1 InvalidKeyException (java.security.InvalidKeyException)1 Key (java.security.Key)1 MessageDigest (java.security.MessageDigest)1 PublicKey (java.security.PublicKey)1 SignatureException (java.security.SignatureException)1 UnrecoverableKeyException (java.security.UnrecoverableKeyException)1 ParseException (java.text.ParseException)1 SimpleDateFormat (java.text.SimpleDateFormat)1