Dapr 入门教程之中间件

Dapr 入门教程之中间件

作者:阳明 2022-09-30 06:36:25

云计算

云原生 通过 Dapr 配置添加的其他中间件会按定义顺序添加到管道中,该管道适用于所有 Dapr API 端点,包括状态、发布/订阅、服务调用、绑定、安全等。

Dapr 允许通过链接一系列中间件组件来定义自定义处理管道。一个请求在被路由到用户代码之前会经过所有定义的中间件组件,然后在返回到客户端之前以相反的顺序经过定义的中间件。

Dapr 中间件

Dapr 中间件

当启动的时候,Dapr sidecar 会构造一个中间件处理管道。默认情况下,管道由 tracing 中间件和 CORS 中间件组成。通过 Dapr 配置添加的其他中间件会按定义顺序添加到管道中,该管道适用于所有 Dapr API 端点,包括状态、发布/订阅、服务调用、绑定、安全等。

如以下配置示例定义了一个使用 OAuth 2.0 中间件和大写中间件组件的自定义管道。在这种情况下,所有请求都通过 OAuth 2.0 协议进行授权,并转换为大写,然后再转发给用户代码。

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
httpPipeline:
handlers:
-name: oauth2
type: middleware.http.oauth2
-name: uppercase
type: middleware.http.uppercase

与其他构建块组件一样,中间件组件是可扩展的,目前 Dapr 已经支持的中间件如下表所示。

中间件

描述

状态

组件版本

OAuth2 Authorization Grant flow

在 Web API 上启用 OAuth2 授权授予流

Alpha

v1

OAuth2 Client Credentials Grant flow

在 Web API 上启用 OAuth2 客户端凭据授予流

Alpha

v1

OpenID Connect

在 Web API 上使用 OpenID Connect 验证持有者令牌

Alpha

v1

Rate limit

限制每秒允许的 HTTP 请求的最大请求数

Alpha

v1

Rego/OPA Policies

将 Rego/OPA 策略应用于传入的 Dapr HTTP 请求

Alpha

v1

RouterChecker

使用 RouterChecker 中间件来阻止无效的 http 请求路由

Alpha

v1

Sentinel

使用 Sentinel 中间件保证应用程序的可靠性和弹性

Alpha

v1

Uppercase

将请求正文转换为大写字母 (demo)

Stable

v1

WASM

在 HTTP 管道中使用 WASM 中间件

Alpha

v1

这些中间件的实现源码位可以在 Github 仓库 https://github.com/dapr/components-contrib/tree/master/middleware/http 中找到。

自定义中间件

Dapr 使用 FastHTTP 来实现其 HTTP 服务器,所以自定义的 HTTP 中间件需要编写为 FastHTTP handler,你的中间件需要实现一个如下所示的 Middleware 接口:

packagemiddleware
import (
"github.com/valyala/fasthttp"
)
typeMiddlewareinterface {
GetHandler(metadataMetadata) (func(hfasthttp.RequestHandler) fasthttp.RequestHandler, error)
}

该接口定义了一个返回 fasthttp.RequestHandler 和 error 的 GetHandler 方法。我们自定义的中间件处理程序实现可以包括任何入站逻辑、出站逻辑:

func (m*customMiddleware) GetHandler(metadataMetadata) (func(fasthttp.RequestHandler) fasthttp.RequestHandler, error) {
varerrerror
returnfunc(hfasthttp.RequestHandler) fasthttp.RequestHandler {
returnfunc(ctx*fasthttp.RequestCtx) {
h(ctx)
}
}, err
}

然后你可以将你自定义的中间件组件贡献给 components-contrib 存储库。当 components-contrib 接受你的提交后,然后需要在 Dapr 运行时的仓库中的 https://github.com/dapr/dapr/tree/master/cmd/daprd/components 下面添加一个中间件注册文件。

注册中间件

比如 uppercase 中间件的注册如下代码所示:

packagecomponents

import (
"strings"

"github.com/valyala/fasthttp"

"github.com/dapr/components-contrib/middleware"
httpMiddlewareLoader"github.com/dapr/dapr/pkg/components/middleware/http"
httpMiddleware"github.com/dapr/dapr/pkg/middleware/http"
"github.com/dapr/kit/logger"
)
funcinit() {
httpMiddlewareLoader.DefaultRegistry.RegisterComponent(func(loglogger.Logger) httpMiddlewareLoader.FactoryMethod {
returnfunc(metadatamiddleware.Metadata) (httpMiddleware.Middleware, error) {
returnfunc(hfasthttp.RequestHandler) fasthttp.RequestHandler {
returnfunc(ctx*fasthttp.RequestCtx) {
body :=string(ctx.PostBody())
ctx.Request.SetBody([]byte(strings.ToUpper(body)))
h(ctx)
}
}, nil
}
}, "uppercase")
}

不过我们也可以发现 Dapr 对于中间件的扩展并没有完全放开,如果用户有特定的需求需要将代码在主仓库中进行更新,这势必也降低了灵活性,不过也可以避免因为低质量的中间件造成 Dapr 各种问题。

OAuth 中间件示例

接下来我们配置一个 OAuth 中间件来说明下 Dapr 中中间件的使用方法。通过配置一个 OAuth 中间件,在不修改应用程序的情况下在 Web API 上启用 OAuth 授权。这种设计将认证/授权问题从应用程序中分离出来,因此应用程序运维人员可以采用和配置认证/授权提供者而不影响应用程序代码。

dapr oauth 中间件

这里我们在 K8s 集群中使用 ingress-nginx 作为 ingress 控制器,如果没有安装可以使用下面的 Helm chart 来快速安装:

helmrepoaddingress-nginxhttps://kubernetes.github.io/ingress-nginx
helminstallmy-releaseingress-nginx/ingress-nginx

首先我们编写了一个使用 Node.js 开发的 echoapp,如下所示:

constexpress=require("express");
constbodyParser=require("body-parser");
constapp=express();
app.use(bodyParser.json());
constport=3000;
app.get("/echo", (req, res) => {
vartext=req.query.text;
console.log("Echoing: "+text);
res.send("Access token: "+req.headers["authorization"] +" Text: "+text);
});

app.listen(port, () =>console.log(`NodeApplisteningonport${port}!`));

然后编写了一个 /echo 接口,获取了请求 header 头中的 authorization 信息和客户端的请求文本信息。

接下来我们这里使用 Github 来实现认证授权,首先前往 https://github.com/settings/developers 注册一个 OAuth 应用,如下所示:

新建 OAuth 应用

这里我们指定的应用 URL 为 http://echo.dapr.local,点击 Register application 注册新应用,注册后在应用详情页面可以获取到 clientId 信息,clientSecret 信息需要手动点击 Generate a new client secret 按钮获取,将该两个参数值记录下来,后续会使用到。

获取clientSecret

然后将我们的 echoapp 应用部署到 Kubernetes 集群中去,对应的资源清单如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
name: echoapp
labels:
app: echo
spec:
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "echoapp"
dapr.io/app-port: "3000"
dapr.io/config: "pipeline"
spec:
containers:
-name: echo
image: dapriosamples/middleware-echoapp:latest
ports:
-containerPort: 3000
imagePullPolicy: Always
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
spec:
ingressClassName: nginx
rules:
-host: echo.dapr.local
http:
paths:
-backend:
service:
name: echoapp-dapr
port:
number: 80
path: /
pathType: Prefix

注意上面我们创建了一个 Ingress 对象,用来暴露 echoapp 应用,需要注意的是我们并没有主动创建 Service 对象,而是直接关联的 echoapp-dapr 这个 Service,其 80 端口映射到 echoapp 应用的 dapr sidecar 中的 3500 端口。

另外注意上面为应用添加的注解,其中有一个 dapr.io/config: “pipeline”,这是用来指定使用的配置对象的,所以我们还需要创建一个名为 pipeline 的 Configuration 对象:

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
spec:
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"
httpPipeline:
handlers:
-type: middleware.http.oauth2
name: oauth2

这里我们为 echoapp 应用配置了一个 middleware.http.oauth2 类型的中间件,对应处理器的名称为 oauth2,该处理器对应中 Dapr 中的一个 Component 组件,如下所示:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2
spec:
type: middleware.http.oauth2
version: v1
metadata:
-name: clientId
value: "<client-id>"
-name: clientSecret
value: "<client-secret>"
-name: scopes
value: ""
-name: authURL
value: "https://github.com/login/oauth/authorize"
-name: tokenURL
value: "https://github.com/login/oauth/access_token"
-name: redirectURL
value: "http://echo.dapr.local"
-name: authHeaderName
value: "authorization"

要使用 Dapr OAuth 中间件,需要配置以下信息:

  • Client ID
  • Client secret
  • Scopes
  • Authorization URL
  • Token URL

下表是一些比较热门授权服务器的 Authorization/Token URLs:

Server

Authorization URL

Token URL

Azure AAD

https://login.microsoftonline.com/{tenant}/oauth2/authorize

https://login.microsoftonline.com/{tenant}/oauth2/token

GitHub

https://github.com/login/oauth/authorize

https://github.com/login/oauth/access_token

Google

https://accounts.google.com/o/oauth2/v2/auth

https://accounts.google.com/o/oauth2/token https://www.googleapis.com/oauth2/v4/token

Twitter

https://api.twitter.com/oauth/authorize

https://api.twitter.com/oauth2/token

我们这里使用的 GitHub 的授权服务器配置,还要注意最后添加的 authHeaderName: authorization 属性,上面我们代码中就是从 Header 头从获取的 authorization 的值。

接下来创建上面的所有资源对象即可,创建完成后记得要将 echo.dapr.local 域名映射到 ingress 控制器。

$kubectlgetpods
NAMEREADYSTATUSRESTARTSAGE
echoapp-b7f5469cb-hzvth2/2Running051s
$kubectlgetsvc
NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGE
echoapp-daprClusterIPNone<none>80/TCP,50001/TCP,50002/TCP,9090/TCP69m
$kubectlgetingressecho-ingress
NAMECLASSHOSTSADDRESSPORTSAGE
echo-ingressnginxecho.dapr.local192.168.0.528059m

然后接下来我们就可以在浏览器中输入 http://echo.dapr.local/v1.0/invoke/echoapp/method/echo?text=hello 来访问应用中的 echo 方法了,正常访问的时候会出现 502 错误,不符合预期。

502错误

这是因为从 Dapr 1.4 版本开始,daprd 进程就被锁定为只接受来自 pod 边界的连接,以实现良好的安全措施。如果要启用外部调用 Dapr,则需要在应用中添加以下注解:

dapr.io/sidecar-listen-addresses: "0.0.0.0"

将该注解添加到 Deployment 中,更新后再次访问 http://echo.dapr.local/v1.0/invoke/echoapp/method/echo?text=hello 就正常了,第一次会跳转到 GitHub 进行授权。

github 授权

授权后会自动跳转回来,正常就会显示 echo 接口返回的数据,包括 Access Token 的数据和 text 参数的值。

echo 方法

到这里我们就实现了在 Dapr 中为应用启用 OAuth 中间件,对原始应用没有任何侵入性。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/292910.html<

赞 (0)
管理的头像管理
上一篇2025-05-20 09:09
下一篇 2025-05-20 09:10

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注