elasticsearch 用于认证请求的简单方法?

wlp8pajw  于 12个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(120)

我试图在Rust中将一个简单的Python requests.get等效为一个“https”域。我要强调的是,我对身份验证、证书、代理等的了解。几乎为零。
我找到了this question,但我不确定这是在做什么:这里似乎没有涉及密码,例如,在那里的答案中,我试图适应我的情况(如下所示),但没有成功。
目的是从本地执行的Elasticsearch服务器获得所需的响应(NB Elasticsearch v8在以前是“http”时变成了“https”。对我来说,这是一个挑战)。Python看起来像这样:

# NB these are valid username and password for an account created in the server setup
username = 'mike12'
password = 'mike12' 
from requests.auth import HTTPBasicAuth
kwargs['auth'] = HTTPBasicAuth(username, password)
# set kwargs['verify'] to the CA (certification authority) certificate path
os.environ['ES_PATH_CONF'] = r'D:\apps\ElasticSearch\elasticsearch-8.6.2\config'
es_path_conf = os.getenv('ES_PATH_CONF')
kwargs['verify'] = fr'{es_path_conf}\certs\http_ca.crt'
try:
    response = requests.request('get', "https://localhost:9500", **kwargs)
except BaseException as e:
    ...

正如你所看到的,为了使它工作,我发现当我做上面的时候,环境变量ES_PATH_CONF必须由代码设置。key“verify”的值是一个路径,指向某种类型的有效证书(因为它在Python中工作),之前已经设置好了。上面的代码运行,并从本地服务器获得预期的200响应,以及正确的响应消息。
这是我在Rust中尝试的:

let login_fields = [
    ("user", "mike12"),
    ("script", "true"),
    ("token", "[TOKEN]"),
    ("password", "mike12"), # is this the right way to add a password???
];
let login_response = client
    .get("https://localhost:9500")
    .form(&login_fields)
    .send()
    .await?
    .text()
    .await?;
println!("{}", login_response);

输出量:

Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: 
"", password: None, host: Some(Domain("localhost")), port: Some(9500), path: "/", query: None, fragment: 
None }, source: hyper::Error(Connect, Os { code: -2146762487, kind: Uncategorized, message: "A certificate 
chain processed, but terminated in a root certificate which is not trusted by the trust provider." }) }

我明白要点。但我不知道解决办法是什么。上面写着“密码:无”我假设提交密码的方式不是我上面所做的。但上面也写着“用户名:所以是的我在挣扎如果在Rust中有文档记录这类东西(除了reqwest documentation),那会有所帮助。

  • 以后**

也许有一些进展:从here中获得灵感。我得到了这个:

use reqwest::Client;
use std::io::Read;
use std::fs::File;
use tmp_env::set_var;
...
    let login_fields = [
        ("user", "mike12"),
        ("script", "true"),
        ("token", "[TOKEN]"),
        ("password", "mike12"), // is this how to add a password???
    ];
    
    let es_path = r#"D:\apps\ElasticSearch\elasticsearch-8.6.2\config"#;
    set_var("ES_PATH_CONF", &es_path);
    
    let mut buf = Vec::new();
    println!("buf {}", str_type_of(&buf));
    let cert_path = format!(r#"{es_path}\certs\http_ca.crt"#);
    println!("cert_path |{}|", cert_path);
    let mut cert_file = File::open(cert_path)?;
    println!("cert_file type {}", str_type_of(&cert_file));
    cert_file.read_to_end(&mut buf);
    println!("buf len now {}", buf.len());

    // let cert = reqwest::Certificate::from_der(&buf)?; // threw error   
    let cert = reqwest::Certificate::from_pem(&buf)?; // delivers cert OK
    println!("cert {:?} type {}", cert, str_type_of(&cert));
    
    let client = Client::builder()
        .add_root_certificate(cert)
        .build()?;
    
    let login_response = client
        .get("https://localhost:9500")
        .form(&login_fields)
        .send()
        .await?
        .text()
        .await?;

    println!("{}", login_response);

当前输出:

{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}

我突然想到,现在发生的事情可能是Elasticsearch特有的。这个特殊的406错误在ES论坛中出现得相当多。从消息来看,这是否意味着ES服务器希望以不同的方式接收用户名和密码,而不是使用表单?注意Python提供它们的方式,作为键“auth”的值(HTTPBasicAuth)。

wtlkbnrh

wtlkbnrh1#

明白了。basic_auth和drop form

let login_response = client
    .get("https://localhost:9500")
    .basic_auth("mike12", Some("mike12"))
    .send()
    .await?
    .text()
    .await?;

相关问题