V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MeloForsaken
V2EX  ›  程序员

网关转发到鉴权,鉴权再转到业务怎么写?

  •  
  •   MeloForsaken · 13 天前 · 2178 次点击
    1. 如何把到网关的请求都转发到鉴权服务上?这个 route 得怎么写?
    2. 转发到鉴权服务上的请求,鉴权后如何再转发到业务上?是重定向到业务服务上?怎么知道端口和 IP ?还是再转会网关?
    31 条回复    2021-11-25 13:14:39 +08:00
    retanoj
        1
    retanoj  
       13 天前
    感觉不是个 route ,是个 filter
    FanError
        2
    FanError  
       13 天前
    最近也在学习这方面东东,似乎现在常用的方案是把鉴权直接在网关上做的。

    业务上不做任何鉴权操作
    MeloForsaken
        3
    MeloForsaken  
    OP
       13 天前
    @retanoj 是的,是我理解错了,但是 filter 里怎么转发到鉴权服务上(不用真正的 ip 和端口)
    sxfscool
        4
    sxfscool  
       13 天前
    业务不做鉴权,鉴权的信息当成参数传递到子服务
    MeloForsaken
        5
    MeloForsaken  
    OP
       13 天前
    @sxfscool @FanError 业务和鉴权分开的啊,鉴权是单独的一个服务
    FanError
        6
    FanError  
       13 天前
    @MeloForsaken 网上的方案全部是在网关上做的,所以不存在转发这个问题

    鉴权通过了,直接到业务模块
    eason1874
        7
    eason1874  
       13 天前
    什么怎么写,不就写拦截器那样写么,这问题问得太宽泛,很难答。你要问具体哪个语言的怎么说,大家还可以给你推荐一些框架例子

    如果不大懂,干脆用软件方案得了,APISIX 之类的开源 API 网关,带控制台,可以像用云厂商 API 网关服务那样配置
    anonydmer
        8
    anonydmer  
       13 天前   ❤️ 1
    1. 是认证还是鉴权?两者不一样。认证容易统一处理,但是鉴权视业务需求而定,复杂的鉴权只能是业务方自己做
    2. 不管你是认证还是授权服务独立出来了,参照一楼,应该用 filter 而不是 route ;如果用 route 不是把鉴权服务又做成网关服务了?
    abersheeran
        9
    abersheeran  
       13 天前
    你是想让鉴权服务提供 RPC ,然后网关去调用吧?
    kifile
        10
    kifile  
       13 天前
    aop 切面,注解鉴权处理
    abobobo
        11
    abobobo  
       13 天前
    网关写个 filter ,在网关验证请求头部带的 token , 验证通过后通过服务名转发到业务上(在 gateway 里配置好 服务名称以及匹配规则)
    retanoj
        12
    retanoj  
       13 天前
    “转发”的意思可以是将 HTTP 请求原封不动的发往另一个目的地
    在这里也可以理解为解析请求,做一些业务逻辑(比如认证检查),再取出一些调用的服务,参数,进行(远程?)服务调用
    nicholasxuu
        13
    nicholasxuu  
       13 天前
    我们是 envoy 鉴权 filter 在 request 上加个 header (内部不会冲突的 header 名,如果用户传了就删掉),然后业务直接读 header 就行了。
    securityCoding
        14
    securityCoding  
       13 天前
    这提问也是醉了,至少带个技术栈啊

    如何把到网关的请求都转发到鉴权服务上?
    自定义 filter

    这个 route 得怎么写?
    route 里面配置一下鉴权的 filter

    转发到鉴权服务上的请求
    不用转发,filter 里面请求认证服务

    鉴权后如何再转发到业务上?
    网关本身就是 proxy 角色,不用再次转发

    是重定向到业务服务上?
    接上

    怎么知道端口和 IP ?
    网关里面一般会有目标服务概念. spring-cloud-gateway 是服务注册名,内置默认 filter 自动查询可用节点

    还是再转会网关?
    网关本身就是 proxy


    综上,你需要先把网关涉及的概念弄清楚,再重新组织一下问题
    SuperShuYe
        15
    SuperShuYe  
       13 天前
    GW 服务(外网):
    gw.abc.com 鉴权后 header 携带 token
    这里配置转发 172.168.0.1 gw.abc.com/order 172.168.0.2 gw.abc.com/user
    Order 服务(内网):
    172.168.0.1 gw.abc.com/order
    User 服务(内网) :
    172.168.0.2 gw.abc.com/user
    Saxton
        16
    Saxton  
       13 天前
    鉴权中心永远只负责鉴权,逻辑不要搞错了,转发权还是在网关身上,目前我们的系统的是
    请求 -》网关-》鉴权-》 网关-》 转发到对应服务,对应的服务不需要在鉴权了,当然有些系统的架构服务的调用也需要额外的鉴权,网关会签发一个临时的调用 TOKEN 和一个用户 TOKEN 一起转发到对应服务,对应服务在拦截这个 token 鉴别,但其实没必要多做一步,你要做的是完全信任鉴权中心和防火墙
    Saxton
        17
    Saxton  
       13 天前
    你也没说你的技术栈是什么
    传统的 springcloud 可以直接在 spring-cloud-gateway 上跑鉴权
    但我的做法我喜欢另外跑一个鉴权中心,这个鉴权中心同时还承担了签证责任,网关永远只是一个负责转发的东西,不要把过多的逻辑压在网关身上
    MeloForsaken
        18
    MeloForsaken  
    OP
       13 天前
    @Saxton 是 springcloud ,没有讲清楚,按你的意思,网关->鉴权->网关,这个得怎么实现?网上没有找到具体的实现方式
    MeloForsaken
        19
    MeloForsaken  
    OP
       13 天前
    @abersheeran @abobobo @nicholasxuu @securityCoding @eason1874 @anonydmer spring cloud ,打个比方 URL 鉴权,网关和鉴权是两个服务,网关具体怎么去调用? RPC ?把鉴权抽离成公共依赖?还是有什么其他比较好的写法?
    yangyaofei
        20
    yangyaofei  
       13 天前 via Android
    oauth2?
    wantooo
        21
    wantooo  
       13 天前
    spring cloud 情况下 request 到网关,自定义 globalFilter 通过 feign 调用鉴权服务,返回结果,决定是继续 chain 还是结束
    qqlyatt
        22
    qqlyatt  
       13 天前   ❤️ 2
    使用 Java 开发正常的业务流程应该是:1.普通浏览不用登录,用户点击某个特殊的 api 或者按钮需要登录。2.需要登录,前端页面,引导用户跳转进入《认证服务器 Authorization-Server 》的《认证》页面,用户在认证页面输入用户名密码或者手机号验证码,确认用户《身份》。3.确认用户后,《认证服务器》返回给前端授权码 authorization_code ,前端 NodeJS 服务器拿着授权码并组织一次 post 请求,在 POST 请求中携带自身的客户端用户名密码以及 redirect_uri ,这个是在《认证服务器》中注册过的客户端 client ,是把前端应用当作一个外来的客户端。这个 redirect_uri 是用来接收令牌 Token 的。《认证服务器》确认过全段服务器的用户名,密码和授权码,再验证当时注册 client 时填写过的 redirect_uri ,一致后,响应一个带有当前用户《身份权限》信息的 Token 。然后前端 NodeJS 将该 Token 存储起来存哪自己看 cookie,session,redis 。每次该用户调用资源服务的时候,也就是你的业务功能的时候,NodeJS 将他的令牌 Token 拿到,用一个类似过滤器的 func 将每次请求的请求头 Header 都加上 Key:Authorization Value:Bearer Token 值。这个请求可以直接发到网关上,也可以不用网关,直接请求到资源服务里,资源服务也能解析这个 Token 确认用户有没有权限请求这个资源。不过你是用网关的,所以,这个请求发到网关上,然后网关上过滤这个请求 Header ,验证这个用户的权限是否和他请求的资源地址匹配,如果不匹配,做出响应 403 无权限响应。如果匹配那就通过,并转发到资源服务器,获取资源服务器响应。如果你配置了 OAuth2+JWT ,网关过滤这一块不用手敲了,只需要简单的配置几下就行。
    qqlyatt
        23
    qqlyatt  
       13 天前
    网关上那个过滤请求 Header 的过程就叫做《鉴权》。
    eason1874
        24
    eason1874  
       13 天前   ❤️ 1
    @MeloForsaken 不是公共依赖,就拦截过滤

    网关->鉴权->网关,这种是把请求转发给 Spring Cloud Gateway 匹配路由执行 Filters ,Filter 把权限信息加在 Headers 之后 Spring Cloud Gateway 再自己把请求转发给业务后端,相当于总共反代两次

    还有一种常见的是类似微服务的形式,鉴权服务不管实际请求,只提供鉴权 HTTP API ,网关收到请求把信息发给鉴权 HTTP API ,拿到权限信息添加到 Headers 转发给后端

    比如用 Nginx + ngx_lua 可以在 rewrite_by_lua 阶段请求鉴权 HTTP API ,把响应的权限信息写入 Nginx 变量,通过 proxy_set_header 传递给后端

    location /openapi/ {
    set $authinfo '';
    rewrite_by_lua_block {
    ... resty.http 请求鉴权内网 HTTP API
    ngx.var.authinfo = 响应的权限信息;
    }
    proxy_set_header "AuthInfo" $authinfo;
    proxy_pass ...请求内网后端的反代配置
    }

    这样后端就可以在 HTTP Header 的 AuthInfo 里取当前用户和权限信息了
    abobobo
        25
    abobobo  
       13 天前   ❤️ 1
    目前我是鉴权+网关一个服务,认证一个服务,一个 url 如果需要登录( token )才能访问,网关的 filter 会对 url 进行鉴权,成功就转发到指定服务,不成功就返回失败提示。用的是 spring-cloud-gateway 跟 JWT 。
    @MeloForsaken
    Saxton
        26
    Saxton  
       13 天前
    @abobobo 一大堆 github -》 zhoutaoo/SpringCloud
    Saxton
        27
    Saxton  
       13 天前   ❤️ 2
    @MeloForsaken @错人了 github-》 /zhoutaoo/SpringCloud
    james2013
        28
    james2013  
       13 天前
    在网关里先调用鉴权接口,成功网关再转发到对应服务
    转发到业务,明显是网关的活,关鉴权什么事?
    nicholasxuu
        29
    nicholasxuu  
       13 天前   ❤️ 1
    @MeloForsaken 什么网关?
    envoy 的话,可以用 ext_authz ( https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_authz/v3/ext_authz.proto ),写个高性能的鉴权 rpc ,envoy 会去调用 rpc ,处理 request ,envoy 再把 request 传给后面的服务。
    jiameng123
        30
    jiameng123  
       13 天前
    可以使用 openresty 实现,在指定的 location 中 rewrite_by_lua 模块中写 lua 脚本,发子请求,子请求应答回来判断成功后,再继续用该 location 后面的逻辑处理
    chenfcheng
        31
    chenfcheng  
       13 天前
    apisix 或者 阿里 api gateway 了解下 ? 鉴权都在网关上做了
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3599 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 05:36 · PVG 13:36 · LAX 21:36 · JFK 00:36
    ♥ Do have faith in what you're doing.