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

SpringBoot 相关问题请教!

  •  
  •   Vanes · 2020-03-09 16:12:04 +08:00 · 4076 次点击
    这是一个创建于 1724 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想来请教一下各位大佬,如下场景如何实现:

    现在服务器有两个 SpringBoot 应用 A 和 B,现在 A 应用需要调用 B 的相关读写接口对某一类数据读写, 但是不希望外部请求直接访问 A 应用提供的 API 来对该类数据进行读写,即该类数据只能由 B 来调用, 个人理解为就是应用 A 对应用 B 授权,然后只有授权了应用才能访问相应的 API,其他外部请求直接拒绝。

    不知道这种场景有什么比较好的实现方式。或者业界有没有什么比较标准的做法?

    32 条回复    2020-03-10 14:01:16 +08:00
    Resource
        1
    Resource  
       2020-03-09 16:14:53 +08:00
    没看懂,我可能语文不太好
    tcfenix
        2
    tcfenix  
       2020-03-09 16:16:37 +08:00
    a 弄一个 auth key 的库,然后对每个可以调用 a 的业务身份随机生成一个 auth key,
    b 请求的时候带着业务身份跟 auth key
    lincya
        3
    lincya  
       2020-03-09 16:16:46 +08:00
    感觉跟缺个登录机制一样。。。
    zhenjiachen
        4
    zhenjiachen  
       2020-03-09 16:18:13 +08:00
    你只要是接口就可能被别人调用,可以用签名或者 oauth2 调用,只要 key 不泄漏别人可以调用你的接口,但是肯定会被拦截
    manami
        5
    manami  
       2020-03-09 16:18:33 +08:00 via Android
    怎么感觉就是单点登录集成机制?
    Vanes
        6
    Vanes  
    OP
       2020-03-09 16:22:41 +08:00
    @Resource 可能是我描述的不太清楚。就是 想实现一个 API 只能让指定客户端来访问,不引入额外的用户角色
    Vanes
        7
    Vanes  
    OP
       2020-03-09 16:25:18 +08:00
    @zhenjiachen 所以可能还是跟普通的带 token 来访问资源的一样是吗? 因为总感觉这样的话有后门
    Vanes
        8
    Vanes  
    OP
       2020-03-09 16:26:44 +08:00
    @tcfenix 这样的话是不是还是 a 的业务身份在起关键作用。
    goldpumpkin
        9
    goldpumpkin  
       2020-03-09 16:28:19 +08:00
    请求的时候,带上系统标识,进行校验
    Kontinue
        10
    Kontinue  
       2020-03-09 16:28:54 +08:00
    API 做个认证不就行了?简单的搞个 token,负载的走阿里云 API 那套。
    https://help.aliyun.com/document_detail/29475.html?spm=a2c4g.11186623.2.13.2aa44ae01LxLfD
    Kontinue
        11
    Kontinue  
       2020-03-09 16:29:40 +08:00
    复杂的
    HangoX
        12
    HangoX  
       2020-03-09 16:30:05 +08:00
    不用那么麻烦啊。。。你内部用内部域名访问,不是来自这几个域名的直接 ban 掉不就好了。
    tinybaby365
        13
    tinybaby365  
       2020-03-09 16:31:48 +08:00
    实现一个 HandlerInterceptor,验证请求方(基于 IP or JWT,随你怎么搞),验证通过的在 HttpServletRequest 里 setAttribute(加个 trusted 标记)。在你的那个 RestController 接口读取 HttpServletRequest 的那个 attribute,判断是否受信。
    Vanes
        14
    Vanes  
    OP
       2020-03-09 16:32:21 +08:00
    @HangoX 那想请教下,如果本地改了 host 呢,是不是就可以伪装了?(当然内部域名好像别人也不知道
    Vanes
        15
    Vanes  
    OP
       2020-03-09 16:33:58 +08:00
    @tinybaby365 就和楼上有位老哥的想法一致,用 request 的参数来控制。 然后是不是只需要担心参数是否被猜到?
    tinybaby365
        16
    tinybaby365  
       2020-03-09 16:35:39 +08:00
    @tinybaby365 此方法的改进是,自定义一个 annotation,HandlerInterceptor 里面判断是否有这个 annotation,有则验证,否则直接 sendError。你的接口加上这个 annotation 就是限制内部访问。
    sagaxu
        17
    sagaxu  
       2020-03-09 16:36:28 +08:00 via Android
    硬是没看明白是 a 调用 b,还是 b 调用 a
    tinybaby365
        18
    tinybaby365  
       2020-03-09 16:38:25 +08:00
    @Vanes JWT + https 了解一下。或者 Mutual TLS。
    renyijiu
        19
    renyijiu  
       2020-03-09 16:39:13 +08:00
    我们系统是 header 增加一个特定参数,带有系统 token 校验,另外自定义个注解 @Internal 标识内部接口
    Vanes
        20
    Vanes  
    OP
       2020-03-09 16:40:06 +08:00
    @tinybaby365 所以就得改写原有的 Token 颁发机制,里面加一个类似于 trusted 的标记的属性是吗?
    Vanes
        21
    Vanes  
    OP
       2020-03-09 16:42:15 +08:00
    @renyijiu 所以内部接口和外部接口对于客户端来说,区别就在于 header 是吗?
    renyijiu
        22
    renyijiu  
       2020-03-09 16:49:40 +08:00
    @Vanes #21 通过注解判断内外部接口,从而进行不同的校验(客户端的请求需要签名等验证),另外外层有网关,可以设置名单内部接口拒绝外部访问
    0ray
        23
    0ray  
       2020-03-09 17:42:47 +08:00
    为啥一定要用调 api, 作成 rpc 通信不好吗, 集成 dubbo 很容易的.
    mazyi
        24
    mazyi  
       2020-03-09 18:11:48 +08:00
    给一把钥匙不就行了。。。
    NizumaEiji
        25
    NizumaEiji  
       2020-03-09 18:30:15 +08:00
    写过滤器\拦截器带个鉴权也行
    或者直接 b 机器上本地改下 dns a 机器的 ng 上弄个规则 特定的接口拒绝外网 ip 访问也行吧
    m1ch3ng
        26
    m1ch3ng  
       2020-03-09 19:19:13 +08:00
    用 token 的机制不就可以(必须携带某些请求头)
    mosliu
        27
    mosliu  
       2020-03-09 22:55:28 +08:00
    做鉴权不行么 ?
    wozhizui
        28
    wozhizui  
       2020-03-10 07:46:20 +08:00
    这应该就是加权限的 api 吧,行业软件的 api 经常都这么搞,给个调用者一个 key,请求的时候带上 key,然后应用 B 返回 200 ok 或者 400 不 ok。
    已经有挺专业的回答了。
    CRUD
        29
    CRUD  
       2020-03-10 10:30:44 +08:00
    1、A 应用只对 B 应用提供服务的情况下可关闭外网访问,B 请求 A 走内网。
    2、A 应用除了对 B 应用提供服务,还需要对其他应用提供服务的情况下引入鉴权机制,可以是 token 也可以是 auth key,本质上只是 A 服务颁发给调用它的客户端的一个凭证,请求时带上该凭证,验证通过执行剩余逻辑,验证错误拒绝请求而已。
    Leiothrix
        30
    Leiothrix  
       2020-03-10 11:03:48 +08:00
    B 应用配置 Spring Security 规则,只暴露该暴露出去的接口,A 应用后台登录后可以无阻碍访问 B 应用未暴露(保护)接口。
    HansCathy
        31
    HansCathy  
       2020-03-10 11:21:55 +08:00
    我理解 B 是对外接口,A 是对内接口。在网关配置 A 为登录验证,B 为匿名验证 就可以了
    xyshmily
        32
    xyshmily  
       2020-03-10 14:01:16 +08:00
    ng 白名单
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5441 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 07:34 · PVG 15:34 · LAX 23:34 · JFK 02:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.