Skip to content

IBM API Connect #179

Open
Open
@uniquejava

Description

@uniquejava

总结

Citi的portal: https://sandbox.developerhub.citi.com/

几个坑点

  1. Bluemix上的文档在写Token URL时用了/oauth2/authorize, 实际上要写全路径(包含endpoint)才可以, 不然在authorize的时候会报404错误. 其中<API_END_POINT>的地址, 在Settings > Gateways中可以找到, 比如
    https://api.au.apiconnect.ibmcloud.com/orgccs-spacefd/sandbox

还有一个更深的坑, 这个API_END_POINT最后一部分/sandbox是可以修改的, 值必须和Settings>Overview中的Name保持一致, 不然在authorize的时候也会报404错误

  1. 任何一个Product都先要在Portal中Subscribe才可使用(只要用到的product都要分别Subscribe), 并且 每个developer自己注册的app,都要分别subscribe.. (共需要点m*n次subscribe) -- Citi的portal消除了这个坑, 完全无需subscribe. 规避方法之一是将所有的API都放在一个product里面, 这样只要订阅一次.

  2. Bluemix上的文档在publish product的时候, 每个product里面都包含了两组API, 一组是业务相关的, 一组是OAuth Provider API, 这样在developer订阅了这个product后, 就能使用/token和相应的api服务. 但是每个product里边都要包含一个OAuth Provider API, 是不是太过折腾.我试了一下, 在product中根本不需要包含OAuth Provider API. Citi的做法是, 将authorize和token api单独打包成一个叫Authentication的product, 并publish, 这样developer只要订阅一次这个Authentication的product, 就可以在任意Product里面使用这个auth/token API.

  3. 直接拿通过client_credentials得到的token,调用受auth code保护的API, 竟然也能通过权限认证. 对于这个漏洞, 目前的做法是在后台增加SecurityInterceptor, 从header中取ibm-app-user, 前一种认证方式ibm api connect会自动将client key放进去, 后一种是自己放入的customer信息. 通过对这个值进行判断, 能得到当前developer传的token的类型. 如果类型不匹配, throw 401 error.

定义和发布API的流程

  1. 在bluemix中新建API Connect Service(最多只能建一个这样的Service)
  2. API Connect用catalog来归类不同的环境(比如dev, sit, prod), 默认会建一个叫Sandbox的Catalog, 相当于开发环境.
  3. 在Catalog > Drafts > APIs中通过API Designer定义API (也可以不使用API Designer直接导入swagger ui生成的json文件
  4. 对于每个API需要切换到Assemble页面, 定义一个对应的Policy(一般会使用Switch Operation + Invoke或Proxy), Proxy比较实用, 能自动将header, request params, request body原封不动地传给后台的API)
  5. 到此为止, 可以在Assemble页点那个▶️按钮测试这个API(那个页面有个republish product按钮, 修改了assemble后要点republish product 然后 RUN才会生效).
  6. 之后如果在API Designer中修改了配置, 需要点保存, 然后切到Drafts > Product, 点那个 Stage to Sandbox的按钮 (小心这个按钮会把已经处于publish状态的product变成 stage状态)
  7. stage的下一步必定是切到Dashboard中的Product页面, 点一下publish按钮(折腾)
  8. 不要乱点🏠, 使用那个>>图标切换, 所谓的navigation panel..

一句话: 在Drafts-APIs页面配置API, 在Assemble中做API映射以及测试, 在Drafts-Products-Product页面Stage, 在Dashboard-Products页面Publish.

API Security

在API Designer左边的Security Definition中定义要使用哪种Security(一共有API Key, xx和OAuth)三种, 中间那个叫什么名字, 我忘记了(说明不重要:lol)
同时必定要在API Designer左边的Security中勾选上一个Section中定义的Definition, 又是这种毫无意义的操作.

即stage和publish总是成对出现, Security Definition和Security总是成对出现.

  1. 我不知道API KEY存在的作用是什么. 估计适用于hello world这样简单的场景, 就是在请求api的时候通过header中传两个固定的key, 分别是Client-ID和Client-Secret.
  2. 我们不做hello world, 所以只用到了OAuth

添加OAuth 2.0 Provider API

如果要在自定义的API中使用类型为OAuth的Security Definition, 则必须先添加另外一组内置的API, 名字叫OAuth 2.0 Provider API. 这组内置的API和你自己定义的API有很多相同之处,比如base path, paths, operations. 它在OAuth体系中相当于Authorization Server的角色, 因此它预定了在两个path, 分别是/oauth2/authorize/oauth2/token, 并且规定了各自要求的参数类型(注意第二个Operation: /oauth2/token要求参数必须以Form Data的方式提交).

OAuth 2区块

这个是相比自定义API多出来的一块, 也是最难懂的一块.

  1. Client type: Public/Confidential(这个选项真的是多此一举,分别对应OAUTH中的2-legged和3-legged)..
  2. Scopes: 对应OAuth中的scope. 比如一个精典的app可以有read, write, delete三种scope. (其它API中的scope必须是这里定义的scopes的子集, 然后在其它自定义API中定义的scope description会覆盖这里写的scope description, 我们的项目并没有区分scope(目前仅定义了一个唯一的scope)
  3. Grants: IBM又一个增加产品复杂度的设定内容, 表示你的Authorization Server支持哪些grant types. 它把OAuth中的Client Credentials叫做Application, 把Authorization Code叫Access Code..你妈, 无谓的多出两个要记的名词. 我们的产品目前使用的grant type是Password.
  4. Identity extraction - Collect credentials using选择Basic, 表示IBM API Connect将会把client传过来的username和password值, 以Basic Auth的方式传给Authentication URL.
  5. Authenticate application users using: 选择Authentication URL
  6. Authentication URL: 填你的后台API专门做authenticate的API的路径, 只要response code为200, 就表示认证通过, 其它状态码表示认证失败. 可以在你的Authenticate API的response header中添加一个叫``的key. IBM API Connect会把这个key的内容添加到它生成的access_token中. 在它内部解析access_token的时候会把这个值取出来以一个叫ibm-app-user的值通过request header传给你的API.(妈呀, 文档中只字未提ibm-app-user, 通过在expressjs中打印req.headers我才知道有这么个东西.)

Difference between the “Resource Owner Password Flow” and the “Client Credentials Flow”

使用OAuth Provider API

就是用上面配置的OAuth 2.0 Provider API来保护你自己的API(需要在你所有的API中都设置一遍), 套路如下:

1. Security Definitions

添加OAuth,
Name写一个有意义的名字比如OAuth吧 (这个Name会出现在API Product Detail页面上做为帮助文档的一部分)
Flow选择 implicit/password/application/access code之一,
Token URL输入: <API_END_POINT>/<OAUTH2_PROVIDER_API_BASE_PATH>/oauth2/token
Flow必须是在Provider中声明的grants type之一, 我们用的Password.

Scopes: 添加一个或多个当前API用到的Scope, 必须是在Provider中定义的Scopes的子集.

2. Security

勾上上一步创建的OAuth和scope

References

  1. Creating a security definition
  2. Creating an OAuth provider API
  3. API Connect for IBM Cloud context variables
  4. Tutorial: Securing an API by using OAuth 2.0
  5. API Connect Tutorial: Mastering the API Assembly
  6. Bluemix上的Tutorial

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions