我有许多使用OAuth Bearer令牌进行身份验证的服务。我可以使用OAuth客户端凭据授予或资源所有者凭据授予来获取令牌。
但是,我有许多现有系统,仅能使用经过相互TLS身份验证的连接进行身份验证的呼叫。
我不是想更新所有调用应用程序以获取OAuth承载令牌,而是想构建一个网关代理,
基本上,我想向旧客户端隐藏OAuth的使用情况,并允许它们仅与Mutual TLS身份验证一起使用。
是否存在用于Ngnix,Apache,Envoy或类似HTTP反向代理的现有反向代理或方式或模块,而无需构建完整的代理即可实现?
我发现很多模块可以处理使用各种模块将Apache和Ngnix设置为OAuth中继方或资源服务器的情况,
但是找不到用作OAuth或Open ID Connect客户端作为经过TLS身份验证的客户端的代理的任何示例。
特别是我想避免编写代理部分。即使我必须编写实际的OAuth交互脚本。我找到的最接近的东西是这个blog post on implementing an OAuth RP in Envoy lua scripts。
我很难想象这是一个独特的需求,所以我想知道是否有我没有找到的该模式的任何标准实现。
答案 0 :(得分:0)
事实证明,使用Envoy代理很容易做到这一点。特别是通过使用External Authorization HTTP Filters。
可以通过在侦听器上设置Downstream TLS Context并将require_client_certificate
设置为true
来配置Envoy代理以执行SSL终止并要求客户端证书。
可以配置HTTP Connection Manager Network Filter以在对上游服务的请求上设置x-forwarded-client-cert
头。将forward-client-cert-details设置为SANITIZE_SET
会导致特使设置标头。可以通过设置set-current-client-cert-details来配置标题中包含的内容。
但是要真正让Envoy进行令牌交换,我们需要配置一个外部授权过滤器。这使特使可以使用请求的详细信息(包括证书)来调用服务,并且该服务可以决定是否允许该请求。至关重要的是,在允许的情况下,它能够向对上游服务的请求中添加标头,从而使其能够添加oauth所需的承载令牌。
外部授权过滤器有网络过滤器版本和HTTP过滤器版本。如果要向上游请求添加标头,则必须使用HTTP。
生成的特使配置如下:
static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
stat_prefix: ingress_http
forward_client_cert_details: SANITIZE_SET # Include details of the client certificate in the x-forwarded-client-cert header when calling the upstream service
set_current_client_cert_details:
subject: True # Include the subject of the certificate in the x-forwarded-client-cert header rather than just the certificate hash.
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: service_backend
http_filters:
- name: envoy.ext_authz # Call an authorization service to do the OAuth token exchange
config:
grpc_service:
envoy_grpc:
cluster_name: auth_service
timeout: 5s # The timeout before envoy will give up waiting for an auth service response and deny access
- name: envoy.router
tls_context:
require_client_certificate: True # Require downstream callers to provide a client certificate
common_tls_context:
validation_context:
trusted_ca:
filename: /etc/envoy/certs/ca-chain.cert.pem # CA certificate that client certificate must be signed with to be accepted
tls_certificates:
- certificate_chain:
filename: /etc/envoy/certs/server-cert.pem
private_key:
filename: /etc/envoy/certs/server-key.pem
password:
inline_string: password
clusters:
- name: auth_service
connect_timeout: 1s # The timeout before envoy will give up trying to make a TCP connectio to an auth service
type: LOGICAL_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
http2_protocol_options: {} # GRPC services must be HTTP/2 so force HTTP/2
load_assignment:
cluster_name: auth_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: localhost
port_value: 8080
然后,诀窍是实现GRPC服务,该服务实现External Authorization Protcol进行令牌交换,并拒绝请求或提供Authorization
头以将承载令牌包括在上游请求中。 / p>
答案 1 :(得分:0)
如果您仍然需要此功能,则可以构建一个使用本地身份验证数据库工作的授权服务器。将其转换为OIDC并接收要注入的令牌非常容易。 https://github.com./fams/tlsjwt-gw