Search in sources :

Example 6 with VerifierResult

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

the class PolicyVerifierImpl method doVerifyInternal.

@Override
protected VerifierResult doVerifyInternal(ServerAuthorizationRequest request) throws Exception {
    Verifier vf = getPolicyLoader().call();
    if (vf != null) {
        return vf.verify(request);
    }
    VerifierResult vr = new VerifierResult();
    vr.setMessage("No verifier found in loaded auth policy");
    return vr;
}
Also used : VerifierResult(com.disney.http.auth.server.VerifierResult) Verifier(com.disney.http.auth.server.Verifier) AbstractVerifier(com.disney.http.auth.server.AbstractVerifier)

Example 7 with VerifierResult

use of com.disney.http.auth.server.VerifierResult 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)

Example 8 with VerifierResult

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

the class TestBasicAuth method testBasic.

@Test
public void testBasic() throws Exception {
    BasicVerifierImpl verifier = new BasicVerifierImpl();
    Map<String, String> pmap = new HashMap<String, String>();
    List<String> accessList = new ArrayList<String>();
    ACLAccessControllerImpl acl = new ACLAccessControllerImpl();
    acl.setAcl(accessList);
    pmap.put("mykey", "mypass");
    PasswordChecker pc = new MapPasswordChecker(pmap);
    verifier.setPasswordCheckers(Arrays.asList(pc));
    verifier.setAccessControllers(Arrays.asList((AccessController) acl));
    MockHttpServletRequest request = new MockHttpServletRequest();
    ServerAuthorizationRequest areq = new ServletAuthorizationRequest(request);
    VerifierResult result = verifier.verify(areq);
    Assert.assertEquals(ERROR_MISSING_CREDENTIALS, result.getMessage());
    request.addHeader("Authorization", "Basic " + DatatypeConverter.printBase64Binary("mykey:wrongpass".getBytes()));
    result = verifier.verify(areq);
    Assert.assertEquals(ERROR_UNKNOWN_CREDENTIALS, result.getMessage());
    request = new MockHttpServletRequest();
    request.addHeader("Authorization", "Basic " + DatatypeConverter.printBase64Binary("mykey:mypass".getBytes()));
    areq = new ServletAuthorizationRequest(request);
    result = verifier.verify(areq);
    Assert.assertTrue("Expected successful authentication", result.isAuthenticated());
    Assert.assertFalse("Expected failed authorization", result.isAuthorized());
    accessList.add("mykey");
    result = verifier.verify(areq);
    Assert.assertTrue("Expected successful authentication", result.isAuthenticated());
    Assert.assertTrue("Expected successful authorization", result.isAuthorized());
}
Also used : HashMap(java.util.HashMap) MockHttpServletRequest(org.springframework.mock.web.MockHttpServletRequest) ArrayList(java.util.ArrayList) ServletAuthorizationRequest(com.disney.http.auth.server.ServletAuthorizationRequest) PasswordChecker(com.disney.http.auth.server.basic.PasswordChecker) MapPasswordChecker(com.disney.http.auth.server.basic.MapPasswordChecker) AccessController(com.disney.http.auth.server.AccessController) VerifierResult(com.disney.http.auth.server.VerifierResult) ACLAccessControllerImpl(com.disney.http.auth.server.ACLAccessControllerImpl) MapPasswordChecker(com.disney.http.auth.server.basic.MapPasswordChecker) ServerAuthorizationRequest(com.disney.http.auth.server.ServerAuthorizationRequest) BasicVerifierImpl(com.disney.http.auth.server.basic.BasicVerifierImpl) Test(org.junit.Test)

Example 9 with VerifierResult

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

the class TestHttpSignature method testSigning.

@Test
public void testSigning() throws Exception {
    SignatureVerifierImpl verifier = new SignatureVerifierImpl();
    verifier.setMaxDateDrift(5000);
    final KeyStore testStore = KeyStore.getInstance("JCEKS");
    testStore.load(null);
    Key hmac256key = new SecretKeySpec("hello world".getBytes(), "HmacSHA256");
    testStore.setKeyEntry("hmac256key", hmac256key, new char[0], null);
    verifier.setKeyChains(Arrays.asList((KeyChain) new KeyStoreKeyChainImpl(new Callable<KeyStore>() {

        @Override
        public KeyStore call() throws Exception {
            return testStore;
        }
    }, new char[0])));
    DateFormat headerDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
    verifier.setRequiredHeaders(Arrays.asList(REQUEST_TARGET, "date"));
    MockHttpServletRequest request = new MockHttpServletRequest();
    ServerAuthorizationRequest areq = new ServletAuthorizationRequest(request);
    // FIRST TEST: missing signature
    VerifierResult result = verifier.verify(areq);
    Assert.assertEquals(ERROR_MISSING_SIGNATURE, result.getMessage());
    SignatureAuthorization signature = new SignatureAuthorization();
    signature.setAlgorithm("rsa-sha256");
    signature.setKeyId("rsa256key");
    signature.setHeaders(new ArrayList<String>());
    signature.setSignature(new byte[0]);
    request.addHeader("Authorization", "Signature " + signature.toString());
    // SECOND TEST: missing REQUEST_TARGET
    result = verifier.verify(areq);
    Assert.assertEquals(MessageFormat.format(ERROR_MISSING_HEADER_FORMAT, REQUEST_TARGET), result.getMessage());
    signature.setHeaders(Arrays.asList(REQUEST_TARGET));
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.addHeader("Authorization", "Signature " + signature.toString());
    // THIRD TEST: missing date
    result = verifier.verify(areq);
    Assert.assertEquals(MessageFormat.format(ERROR_MISSING_HEADER_FORMAT, "date"), result.getMessage());
    signature.setHeaders(Arrays.asList(REQUEST_TARGET, "date"));
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.addHeader("Authorization", "Signature " + signature.toString());
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 6000)));
    // FOURTH TEST: out-of-range date
    result = verifier.verify(areq);
    Assert.assertEquals(ERROR_INVALID_DATE, result.getMessage());
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.addHeader("Authorization", "Signature " + signature.toString());
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
    // FIFTH TEST: unknown key ID
    result = verifier.verify(areq);
    Assert.assertEquals(MessageFormat.format(ERROR_UNKOWN_KEY_ID_FORMAT, signature.getKeyId()), result.getMessage());
    signature.setKeyId("hmac256key");
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.addHeader("Authorization", "Signature " + signature.toString());
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
    // SIXTH TEST: rsa mismatch
    result = verifier.verify(areq);
    Assert.assertEquals(MessageFormat.format(ERROR_EXPECTED_RSA_FORMAT, signature.getKeyId()), result.getMessage());
    KeyPair keypair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
    X509Certificate certificate = generateCertificate(keypair);
    testStore.setKeyEntry("rsa256key", keypair.getPrivate(), new char[0], new Certificate[] { certificate });
    signature.setKeyId("rsa256key");
    signature.setAlgorithm("hmac-sha256");
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.addHeader("Authorization", "Signature " + signature.toString());
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
    // Seventh TEST: hmac mismatch
    result = verifier.verify(areq);
    Assert.assertEquals(MessageFormat.format(ERROR_EXPECTED_HMAC_FORMAT, signature.getKeyId()), result.getMessage());
    signature.setAlgorithm("rsa-sha256");
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.addHeader("Authorization", "Signature " + signature.toString());
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
    // EIGHT test: invalid signature
    Exception sigEx = null;
    try {
        verifier.verify(areq);
    } catch (Exception e) {
        sigEx = e;
    }
    Assert.assertNotNull(sigEx);
    // NINTH test: good signature
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.setMethod("GET");
    request.setRequestURI("/");
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
    String signingString = "(request-target): get /\ndate: " + request.getHeader("date");
    byte[] sigBytes = signMessage(keypair.getPrivate(), signingString, "rsa-sha256");
    signature.setSignature(sigBytes);
    request.addHeader("Authorization", "Signature " + signature.toString());
    result = verifier.verify(areq);
    Assert.assertTrue("Verification failed", result.isAuthenticated());
    // TENTH test: bad signature
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.setMethod("GET");
    request.setRequestURI("/nogood");
    request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
    signingString = "(request-target): get /\ndate: " + request.getHeader("date");
    sigBytes = signMessage(keypair.getPrivate(), signingString, "rsa-sha256");
    signature.setSignature(sigBytes);
    request.addHeader("Authorization", "Signature " + signature.toString());
    result = verifier.verify(areq);
    Assert.assertFalse("Verification succeed when it should have failed", result.isAuthenticated());
    Assert.assertEquals(ERROR_VERIFICATION_FAILED, result.getMessage());
}
Also used : KeyPair(java.security.KeyPair) MockHttpServletRequest(org.springframework.mock.web.MockHttpServletRequest) ServletAuthorizationRequest(com.disney.http.auth.server.ServletAuthorizationRequest) KeyChain(com.disney.http.auth.keychain.KeyChain) KeyStore(java.security.KeyStore) Callable(java.util.concurrent.Callable) Date(java.util.Date) X509Certificate(java.security.cert.X509Certificate) SignatureException(java.security.SignatureException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SignatureVerifierImpl(com.disney.http.auth.server.signature.SignatureVerifierImpl) KeyStoreKeyChainImpl(com.disney.http.auth.keychain.KeyStoreKeyChainImpl) VerifierResult(com.disney.http.auth.server.VerifierResult) SignatureAuthorization(com.disney.http.auth.SignatureAuthorization) SecretKeySpec(javax.crypto.spec.SecretKeySpec) SimpleDateFormat(java.text.SimpleDateFormat) DateFormat(java.text.DateFormat) SimpleDateFormat(java.text.SimpleDateFormat) Key(java.security.Key) PrivateKey(java.security.PrivateKey) ServerAuthorizationRequest(com.disney.http.auth.server.ServerAuthorizationRequest) Test(org.junit.Test)

Aggregations

VerifierResult (com.disney.http.auth.server.VerifierResult)9 ServerAuthorizationRequest (com.disney.http.auth.server.ServerAuthorizationRequest)4 ServletAuthorizationRequest (com.disney.http.auth.server.ServletAuthorizationRequest)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 AuthenticatedPrincipal (com.disney.http.auth.server.AuthenticatedPrincipal)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 Test (org.junit.Test)3 MockHttpServletRequest (org.springframework.mock.web.MockHttpServletRequest)3 DigestAuthorization (com.disney.http.auth.DigestAuthorization)2 SignatureAuthorization (com.disney.http.auth.SignatureAuthorization)2 KeyChain (com.disney.http.auth.keychain.KeyChain)2 ACLAccessControllerImpl (com.disney.http.auth.server.ACLAccessControllerImpl)2 AbstractVerifier (com.disney.http.auth.server.AbstractVerifier)2 AccessController (com.disney.http.auth.server.AccessController)2 Verifier (com.disney.http.auth.server.Verifier)2 InvalidKeyException (java.security.InvalidKeyException)2 Key (java.security.Key)2 MessageDigest (java.security.MessageDigest)2