Search in sources :

Example 1 with VerifierResult

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

the class VerifierFactory method createVerifier.

@SuppressWarnings("rawtypes")
public Verifier createVerifier(List auths, Class<Script> scriptClass) throws InstantiationException, IllegalAccessException, ClassNotFoundException, MalformedURLException, URISyntaxException, NoSuchAlgorithmException, InvalidKeySpecException, CertificateException {
    ArrayList<Verifier> verifiers = new ArrayList<Verifier>(auths.size());
    for (Object auth : auths) {
        if (auth instanceof Map) {
            Map conf = (Map) auth;
            Object policy = conf.get("policy");
            if (policy != null) {
                verifiers.add(processPolicy(conf, scriptClass));
            } else {
                String type = (String) conf.get("type");
                if ("signature".equals(type)) {
                    verifiers.add(processSignature(conf, scriptClass));
                } else if ("basic".equals(type)) {
                    verifiers.add(processBasic(conf, scriptClass));
                } else if ("digest".equals(type)) {
                    verifiers.add(processDigest(conf, scriptClass));
                } else {
                    throw new IllegalArgumentException("Unkown auth type: " + type);
                }
            }
        } else if (auth instanceof CharSequence) {
            verifiers.add((Verifier) fallbackConstruct(auth, scriptClass));
        } else if (auth instanceof Closure) {
            verifiers.add(new Verifier() {

                @Override
                public VerifierResult verify(ServerAuthorizationRequest request) throws Exception {
                    Object result = ((Closure) auth).call(request);
                    if (!(result instanceof VerifierResult)) {
                        result = DefaultTypeTransformation.castToType(result, VerifierResult.class);
                    }
                    return (VerifierResult) result;
                }
            });
        }
    }
    return new VerifierChain(verifiers);
}
Also used : Closure(groovy.lang.Closure) VerifierChain(com.disney.http.auth.server.VerifierChain) ArrayList(java.util.ArrayList) AbstractVerifier(com.disney.http.auth.server.AbstractVerifier) Verifier(com.disney.http.auth.server.Verifier) URISyntaxException(java.net.URISyntaxException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) MalformedURLException(java.net.MalformedURLException) CertificateException(java.security.cert.CertificateException) VerifierResult(com.disney.http.auth.server.VerifierResult) Map(java.util.Map) HashMap(java.util.HashMap) ServerAuthorizationRequest(com.disney.http.auth.server.ServerAuthorizationRequest)

Example 2 with VerifierResult

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

the class TestDigestAuth method testDigest.

@Test
public void testDigest() throws Exception {
    DigestVerifierImpl verifier = new DigestVerifierImpl();
    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");
    PasswordDigester pc = new MapPasswordDigester(pmap);
    verifier.setPasswordDigesters(Arrays.asList(pc));
    verifier.setAccessControllers(Arrays.asList((AccessController) acl));
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.setRequestURI("/");
    ServerAuthorizationRequest areq = new ServletAuthorizationRequest(request);
    VerifierResult result = verifier.verify(areq);
    Assert.assertEquals(ERROR_MISSING_CREDENTIALS, result.getMessage());
    String challenge = result.getChallenge();
    Pattern noncePattern = Pattern.compile("nonce=\"([^\"]+)\"");
    Matcher matcher = noncePattern.matcher(challenge);
    if (!matcher.find()) {
        throw new Exception("No nonce found in challenge");
    }
    String nonce = matcher.group(1);
    Pattern opaquePattern = Pattern.compile("opaque=\"([^\"]+)\"");
    matcher = opaquePattern.matcher(challenge);
    if (!matcher.find()) {
        throw new Exception("No opaque found in challenge");
    }
    String opaque = matcher.group(1);
    DigestAuthorization ad = new DigestAuthorization();
    ad.setNonce(nonce);
    ad.setCnonce("ClientNonce");
    ad.setNonceCount("000001");
    ad.setOpaque(opaque);
    ad.setQop("auth");
    ad.setUri("/");
    ad.setUsername("mykey");
    ad.setDigest(new byte[0]);
    ad.setRealm(verifier.getRealm());
    request.addHeader("Authorization", ad.toString());
    result = verifier.verify(areq);
    Assert.assertEquals(ERROR_UNKNOWN_CREDENTIALS, result.getMessage());
    // now fix the digest
    /*
		StringBuilder signingString = new StringBuilder();
		signingString.append(digest("mykey",verifier.getRealm(),"mypass"));
		signingString.append(":").append(nonce).append(":").append(ad.getNonceCount()).append(":").append(ad.getCnonce()).append(":auth:");
		signingString.append(digest("GET",ad.getUri()));
		*/
    request = new MockHttpServletRequest();
    areq = new ServletAuthorizationRequest(request);
    request.setMethod("GET");
    request.setRequestURI("/");
    String signingString = ad.generateSigningString("mykey", "mypass", new ServletAuthorizationRequest(request));
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    ad.setDigest(md5.digest(signingString.toString().getBytes()));
    request.addHeader("Authorization", ad.toString());
    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 : DigestAuthorization(com.disney.http.auth.DigestAuthorization) Pattern(java.util.regex.Pattern) HashMap(java.util.HashMap) MapPasswordDigester(com.disney.http.auth.server.digest.MapPasswordDigester) PasswordDigester(com.disney.http.auth.server.digest.PasswordDigester) Matcher(java.util.regex.Matcher) MockHttpServletRequest(org.springframework.mock.web.MockHttpServletRequest) ArrayList(java.util.ArrayList) ServletAuthorizationRequest(com.disney.http.auth.server.ServletAuthorizationRequest) MapPasswordDigester(com.disney.http.auth.server.digest.MapPasswordDigester) AccessController(com.disney.http.auth.server.AccessController) VerifierResult(com.disney.http.auth.server.VerifierResult) MessageDigest(java.security.MessageDigest) ACLAccessControllerImpl(com.disney.http.auth.server.ACLAccessControllerImpl) DigestVerifierImpl(com.disney.http.auth.server.digest.DigestVerifierImpl) ServerAuthorizationRequest(com.disney.http.auth.server.ServerAuthorizationRequest) Test(org.junit.Test)

Example 3 with VerifierResult

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

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

the class WebSocketAuthFilter method doFilter.

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    if (factory == null) {
        this.factory = (GroovityScriptViewFactory) req.getServletContext().getAttribute(GroovityServlet.SERVLET_CONTEXT_GROOVITY_VIEW_FACTORY);
    }
    if (req instanceof HttpServletRequest) {
        HttpServletRequest hreq = (HttpServletRequest) req;
        HttpServletResponse hres = (HttpServletResponse) res;
        if ("websocket".equalsIgnoreCase(hreq.getHeader(UPGRADE_HEADER))) {
            String requestPath = hreq.getPathInfo();
            if (requestPath == null) {
                // when running as default servlet fall back
                requestPath = hreq.getServletPath();
            }
            String socketName = null;
            if (requestPath.startsWith("ws/")) {
                socketName = requestPath.substring(3);
            } else if (requestPath.startsWith("/ws/")) {
                socketName = requestPath.substring(4);
            }
            if (socketName != null) {
                if (log.isLoggable(Level.FINE)) {
                    log.fine("VALIDATING WEB SOCKET REQUEST for socket " + socketName + " " + hreq.getHeader("authorization"));
                }
                try {
                    GroovityScriptView gsv = factory.getSocketByName(socketName);
                    if (gsv != null) {
                        if (gsv.getVerifier() != null) {
                            VerifierResult vf = gsv.getVerifier().verify(new ServletAuthorizationRequest(hreq));
                            if (vf.getAuthenticationInfo() != null) {
                                hres.setHeader(AuthConstants.AUTHENTICATION_INFO, vf.getAuthenticationInfo());
                            }
                            if (vf.isAuthenticated()) {
                                if (vf.isAuthorized()) {
                                    if (vf.getPrincipal() != null) {
                                        hreq = new AuthenticatedRequestWrapper(hreq, vf.getPrincipal());
                                    }
                                } else {
                                    if (log.isLoggable(Level.FINE)) {
                                        log.fine("Verification failed 403 " + vf.getMessage() + ", challenge " + vf.getChallenge());
                                    }
                                    hres.sendError(403, vf.getMessage());
                                    return;
                                }
                            } else {
                                if (vf.getChallenge() != null) {
                                    hres.setHeader(AuthConstants.WWW_AUTHENTICATE_HEADER, vf.getChallenge());
                                }
                                if (log.isLoggable(Level.FINE)) {
                                    log.fine("Verification failed 401 " + vf.getMessage() + ", challenge " + vf.getChallenge());
                                }
                                hres.sendError(401, vf.getMessage());
                                return;
                            }
                            if (log.isLoggable(Level.FINE)) {
                                log.fine("Verification succeeded for " + vf.getPrincipal());
                            }
                        }
                        String origin = hreq.getHeader(ORIGIN_HEADER);
                        String host = hreq.getHeader(HOST_HEADER);
                        if (hreq.isSecure()) {
                            host = "https://".concat(host);
                        } else {
                            host = "http://".concat(host);
                        }
                        if (host.equals(origin)) {
                            // default CORS behavior, allow same-origin requests
                            if (log.isLoggable(Level.FINE)) {
                                log.fine("WebSocket Origin " + origin + " matches host " + host);
                            }
                        } else {
                            AtomicBoolean allowed = new AtomicBoolean(false);
                            CORSProcessor cp = gsv.getCORSProcessor();
                            if (cp != null) {
                                cp.process(hreq, new HttpServletResponseWrapper(hres) {

                                    public void setHeader(String name, String value) {
                                        if (ACCESS_CONTROL_ALLOW_ORIGIN.equals(name)) {
                                            allowed.set(true);
                                        }
                                        super.setHeader(name, value);
                                    }
                                });
                            }
                            if (!allowed.get()) {
                                if (log.isLoggable(Level.FINE)) {
                                    log.fine("Disallowing websocket due to cors violation from " + origin + " to host " + host);
                                }
                                hres.sendError(403, "Origin not allowed");
                                return;
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new ServletException(e);
                }
            }
        }
        chain.doFilter(hreq, hres);
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) GroovityScriptView(com.disney.groovity.servlet.GroovityScriptView) VerifierResult(com.disney.http.auth.server.VerifierResult) AuthenticatedRequestWrapper(com.disney.http.auth.server.AuthenticatedRequestWrapper) ServletAuthorizationRequest(com.disney.http.auth.server.ServletAuthorizationRequest) HttpServletResponseWrapper(javax.servlet.http.HttpServletResponseWrapper) HttpServletResponse(javax.servlet.http.HttpServletResponse) CORSProcessor(com.disney.groovity.servlet.cors.CORSProcessor) ServletException(javax.servlet.ServletException) IOException(java.io.IOException)

Example 5 with VerifierResult

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

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