HTTP Basic Auth
Store username/password list in an edge dictionary, authorize user at the edge, reject requests that don't have correct credentials.
VCL
Use this solution in your VCL service (click RUN below to test this solution or clone it to make changes):
Compute@Edge
Use this solution in your Compute@Edge service:
- Rust
// To generate username/password pairs, on a bash shell you should be able to do: // echo -n "alice:secretpassword" | base64 let mut username_password = HashSet::new(); username_password.insert("YWxpY2U6c2VjcmV0cGFzc3dvcmQ=".to_string());
if let Some(credential) = req .get_header(AUTHORIZATION) .and_then(|header| header.to_str().ok()) .and_then(get_credential) .filter(|credential| username_password.contains(credential)) { // Decode the credential so we can pull the user name out. let bytes = base64::decode(credential)?; let no_secret = str::from_utf8(&bytes)?; let username = get_username(no_secret).unwrap(); req.set_url(HTML_URL); req.remove_header(AUTHORIZATION); req.set_header("authorized-user", &username); log::debug!("Access granted for user {}", username); return Ok(req.send(BACKEND_NAME)?); };
log::debug!("Access denied"); // Catch all other requests and return a 401. let the_body = "\ <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\"> <html> <head> <title>Error</title> <meta HTTP-EQUIV='Content-Type' CONTENT='text/html;'> </head> <body><h1>401 Unauthorized (Fastly)</h1></body> </html>";
Ok(Response::from_body(the_body) .with_status(StatusCode::UNAUTHORIZED) .with_content_type(mime::TEXT_HTML_UTF_8) .with_header(WWW_AUTHENTICATE, "Basic realm=MYREALM"))
fn get_credential(input: &str) -> Option<String> { lazy_static! { static ref RE: Regex = Regex::new(r"Basic (?P<credential>.*)$").unwrap(); } RE.captures(input).and_then(|cap| { cap.name("credential") .map(|credential| credential.as_str().to_owned()) })}