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);
}
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());
}
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;
}
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);
}
}
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;
}
Aggregations