Nginx 使用承载令牌身份验证和代理摘要身份验证的最佳方式是什么?有可能吗?

Nginx 使用承载令牌身份验证和代理摘要身份验证的最佳方式是什么?有可能吗?,nginx,okhttp,squid,digest-authentication,openresty,Nginx,Okhttp,Squid,Digest Authentication,Openresty,我们很少有Web API可以通过承载令牌身份验证流访问。现在,我们还需要使用基于代理的身份验证(例如,Basic、Digest、NTLM)来支持这些API。到目前为止,我能够测试承载令牌身份验证以及基本身份验证,现在我正在探索摘要身份验证 由于承载令牌流使用授权头,而代理摘要身份验证在客户端和代理服务器之间的身份验证流中也存在授权头的重叠/冲突使用。我们能否同时实现两种身份验证方案(承载和代理摘要) 在客户端,我使用了Java中的http摘要库。为了在代理服务器上测试摘要身份验证方案,我

我们很少有Web API可以通过承载令牌身份验证流访问。现在,我们还需要使用基于代理的身份验证(例如,Basic、Digest、NTLM)来支持这些API。到目前为止,我能够测试承载令牌身份验证以及基本身份验证,现在我正在探索摘要身份验证

由于承载令牌流使用授权头,而代理摘要身份验证在客户端和代理服务器之间的身份验证流中也存在授权头的重叠/冲突使用。我们能否同时实现两种身份验证方案(承载和代理摘要)

在客户端,我使用了Java中的http摘要库。为了在代理服务器上测试摘要身份验证方案,我尝试了Squid服务器和Nginx/OpenResty服务器以及Digest_auth模块(),但在任何代理服务器上都没有成功。对于Squid服务器,它将用当前URL的主机(不需要从Web API端)替换从客户端发送的自定义主机头。而在Nginx/OpenResty的情况下,它会发送401,在代理身份验证的情况下,okhttp摘要与之不兼容

OpenResty/Nginx中是否有任何模块可以帮助我从客户端/代理服务器端实现这两种身份验证

目前,我正在研究如何在后续请求中成功地在客户端身份验证时发送承载令牌,尽管我不确定它是否会工作,或者在代理服务器端是否会再次发生冲突

使用okhttp摘要库的客户端代码

import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
import com.burgstaller.okhttp.DispatchingAuthenticator;
import com.burgstaller.okhttp.basic.BasicAuthenticator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.Credentials;
import com.burgstaller.okhttp.digest.DigestAuthenticator;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Test {

    public static String bearerToken = "Bearer abc";

    public static void main(String[] args) throws Exception {

        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.0.3", 80));

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        final Map<String, CachingAuthenticator> authCache = new ConcurrentHashMap<>();

        Credentials credentials = new Credentials("username", "password");
        final BasicAuthenticator basicAuthenticator = new BasicAuthenticator(credentials);
        final DigestAuthenticator digestAuthenticator = new DigestAuthenticator(credentials);

        DispatchingAuthenticator authenticator = new DispatchingAuthenticator.Builder()
                .with("digest", digestAuthenticator)
                .build();

        final OkHttpClient client = builder
                .proxy(proxy)
                .proxyAuthenticator(new CachingAuthenticatorDecorator(authenticator, authCache))
                .addInterceptor(new AuthenticationCacheInterceptor(authCache))
                .addInterceptor(logging)
                .build();

        String url = "http://www.example.com";

        Request request = new Request.Builder()
                .url(url)
                .method("GET", null)
                .addHeader("Host", "admin.example.com")
                .addHeader("Authorization", bearerToken)
                .get()
                .build();
        Response response = client.newCall(request).execute();
        System.out.println(response.body().string());
    }
}
p.S.我想我不能将Nginx摘要认证模块一起使用,因为它总是返回401(使用WWW-Authenticate响应头而不是代理认证响应头)因为它希望在授权请求头中使用摘要身份验证信息,而不是代理授权请求头。因此,为了测试摘要身份验证方案,我需要的是一个转发代理服务器(类似于Squid,但不是Squid本身,因为它会弄乱主机请求头,这在我的用例中是不需要的)它执行代理身份验证而不是服务器身份验证

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    resolver  114.114.114.114;
#    resolver 8.8.8.8;

log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time req_header:"$req_header" req_body:"$request_body" '
'resp_header:"$resp_header" resp_body:"$resp_body"';

lua_need_request_body on;

body_filter_by_lua '
  local resp_body = string.sub(ngx.arg[1], 1, 1000)
  ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
  if ngx.arg[2] then
     ngx.var.resp_body = ngx.ctx.buffered
  end
';

header_filter_by_lua ' 
  local h = ngx.req.get_headers()
  for k, v in pairs(h) do
      ngx.var.req_header = ngx.var.req_header .. k.."="..v.." "
  end
  local rh = ngx.resp.get_headers()
  for k, v in pairs(rh) do
      ngx.var.resp_header = ngx.var.resp_header .. k.."="..v.." "
  end
';
    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        set $resp_body "";
        set $req_header "";
        set $resp_header "";

        auth_digest_user_file /etc/proxy/users_digest;
        auth_digest 'realm';
        proxy_connect;
        proxy_connect_allow            443;
        proxy_connect_connect_timeout  10s;
        proxy_connect_read_timeout     10s;
        proxy_connect_send_timeout     10s;
        
        location / {
        add_header X-DEBUG-MSG-1 "$uri";
        add_header X-DEBUG-MSG-2 "$http_authorization";
        proxy_set_header Host $host;
        proxy_set_header Authorization $http_authorization;
        proxy_pass_header Host;
        proxy_pass_header Authorization;
            proxy_pass $scheme://$host$request_uri;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    server {
        listen       443 ssl;
        server_name  localhost;

        set $resp_body "";
        set $req_header "";
        set $resp_header "";

        auth_digest_user_file /etc/proxy/users_digest;
        auth_digest 'realm';
        proxy_connect;
        proxy_connect_allow            443;
        proxy_connect_connect_timeout  10s;
        proxy_connect_read_timeout     10s;
        proxy_connect_send_timeout     10s;

        ssl_certificate      /etc/ssl/certs/nginx-selfsigned.crt;
        ssl_certificate_key  /etc/ssl/private/nginx-selfsigned.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            add_header X-DEBUG-MSG-1 "$uri";
            add_header X-DEBUG-MSG-2 "$http_authorization";
            proxy_set_header Host $host;
            proxy_set_header Authorization $http_authorization;
            proxy_pass_header Host;
            proxy_pass_header Authorization;
            proxy_pass $scheme://$host$request_uri;
        }
    }
}