文章
· 18 hr 前 阅读大约需 6 分钟

使用 IAM 通过 OAuth 2.0 确保 FHIR 服务器的安全

InterSystems API 管理器(IAM)是 InterSystems IRIS 数据平台的核心组件,提供集中式 API 管理,重点强调安全性。IAM 简化了从创建到退出的整个 API 生命周期,并提供了一个开发人员门户,便于发现和集成 API。访问控制功能允许管理员定义精确的权限,IAM 与 IRIS 数据平台无缝集成,增强了数据管理和集成能力。

IAM 的功能包括

  • API 网关:集中式 API 管理和安全中心。
  • API 生命周期管理:从创建到退出的完整生命周期控制。
  • 安全性:身份验证、授权和数据加密。
  • 监控和分析:使用监控和模式分析工具。
  • 开发人员门户网站:具有文档和测试功能的 API 发现门户。
  • 访问控制:对 API 访问和操作进行细粒度控制。
  • 与 InterSystems IRIS 集成:与 IRIS 数据平台无缝集成。

使用案例: 本报告中的用例是身份和访问管理。

符合 OAuth 2.0 标准的身份验证和授权,使用 IAM 确保 FHIR 服务器的安全。

在本文档中,您将了解如何使用 InterSystems API Manager 通过 OAuth 2.0 确保 FHIR 服务器的安全。OAuth 2.0 是一种广泛使用的授权标准,可使应用程序访问 FHIR 服务器上受保护的资源。InterSystems API 管理器是一种可简化 FHIR API 的创建、管理和监控的工具。按照本文档中的步骤,您将能够配置 InterSystems API Manager 作为 OAuth 2.0 授权服务器,并向授权客户端授予访问令牌。您还将了解如何使用客户端库,使用 OAuth 2.0 将应用程序连接到 FHIR 服务器。

注意:FHIR 服务器仅支持用于 OAuth 2.0 身份验证的 JWT 标记,不支持不透明标记。

本地运行演示的说明:

  1. 在 "命令提示符 "中运行以下命令克隆相关版本库:
    git clone https://github.com/isc-padhikar/IAM_FHIRServer
  2. 进入新克隆的版本库目录,创建一个新目录并命名为 "key"。然后复制一个 iris.key 文件,这是支持 API 管理的 InterSystems IRIS for Health 的许可证。
  3. 然后返回命令提示符,逐个运行以下命令:
    docker-compose build
    docker-compose up
  4. 转到运行 IAM 的 localhost:8002。
  5. 使用 IAM,我可以将 FHIR 服务器作为服务提供,如下图所示:
  6. 定义一个路由,作为 FHIR 服务器的代理(我已将 /fhir 定义为代理),如下图所示:
  7. 然后,定义插件,用于处理向 FHIR 服务器发出的请求、验证和授权对 FHIR 服务器的访问。我们应在 JWT 插件的 "凭据 "部分定义 JWT 令牌的发行方(授权服务器)和通过解码私钥获得的公钥(请参阅即将介绍的 "授权服务器 "部分),如下图所示: 下图显示了使用 Auth0 服务器进行的身份验证和通过 IAM 进行的基于 JWT 令牌的授权。从授权服务器获取 JWT 令牌:使用 JWT 令牌通过 IAM 中定义的代理路由访问 FHIR 服务器:

授权服务器:

使用外部授权服务器及其 Auth0。在接下来的 "用作参考的演示 "部分提到的演示 #1 (FHIROktaIntegration) 的 README 中给出了设置授权服务器的说明。

获取 JSON 网络密钥集 (JWKS) 的端点:https://dev-bi2i05hvuzmk52dm.au.auth0.com/.well-known/jwks.json

它为我们设置的授权服务器提供了一对密钥,可用于使用解码算法检索私钥。

我们将在 IAM 中使用私钥验证 JWT 令牌签名。

从 JWKS 获取公钥的最佳做法是使用编程语言。我在 Python 中使用了以下代码:

import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
import requests
# Replace 'YOUR_DOMAIN' with your actual Auth0 domain
jwks_url = 'https://dev-bi2i05hvuzmk52dm.au.auth0.com/.well-known/jwks.json'
response = requests.get(jwks_url)
jwks = response.json()
# Choose a specific key from the JWKS (e.g., the first key)
selected_key = jwks['keys'][0]
# Decode 'AQAB' (exponent 'e') from Base64 URL-safe to integer
decoded_exponent = int.from_bytes(base64.urlsafe_b64decode(selected_key['e'] + '==='), byteorder='big')
decoded_modulus = int.from_bytes(base64.urlsafe_b64decode(selected_key['n'] + '==='), byteorder='big')
# Construct the RSA public key
public_key = rsa.RSAPublicNumbers(
    decoded_exponent,
    decoded_modulus
).public_key(default_backend())
# Convert the public key to PEM format
public_key_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(public_key_pem.decode('utf-8'))

用作参考的演示:

  1. FHIROktaIntegration:https://openexchange.intersystems.com/package/FHIROktaIntegration该演示展示了如何直接在 InterSystems IRIS for Health 上配置 OAuth 2.0,并将该配置用于 FHIR 服务器。请按照说明配置授权服务器的详细信息。不过,配置完成后在管理门户中是这样的: 这展示了如何在 InterSystems IRIS for Health 中配置 OAuth2.0 以确保 FHIR 服务器的安全。
  2. IAM 从零到英雄:https://openexchange.intersystems.com/package/iam-zero-to-hero

该演示包括 IAM 和 IAM 相关培训。我将对其进行修改,使其具有 FHIR 服务器,并在此演示中使用 IAM 实例与 Auth0 授权服务器进行身份验证,并使用 JWT 插件授权访问。
与之前的演示不同,这次演示使用 IAM 公开 FHIR 服务器端点,并使用 IAM 提供的插件库通过 OAuth 2.0 标准确保其安全。

本演示中的更改

在本演示中,我在 IRIS for Health 实例中添加了 FHIR 服务器。请用以下代码替换 iris.script 文件中的代码:

;do $System.OBJ.LoadDir("/opt/irisapp/src","ck",,1)
zn "%SYS"
Do ##class(Security.Users).UnExpireUserPasswords("*")
set $namespace="%SYS", name="DefaultSSL" do:'##class(Security.SSLConfigs).Exists(name) ##class(Security.SSLConfigs).Create(name) set url="https://pm.community.intersystems.com/packages/zpm/latest/installer" Do ##class(%Net.URLParser).Parse(url,.comp) set ht = ##class(%Net.HttpRequest).%New(), ht.Server = comp("host"), ht.Port = 443, ht.Https=1, ht.SSLConfiguration=name, st=ht.Get(comp("path")) quit:'st $System.Status.GetErrorText(st) set xml=##class(%File).TempFilename("xml"), tFile = ##class(%Stream.FileBinary).%New(), tFile.Filename = xml do tFile.CopyFromAndSave(ht.HttpResponse.Data) do ht.%Close(), $system.OBJ.Load(xml,"ck") do ##class(%File).Delete(xml)

//init FHIR Server
zn "HSLIB"
set namespace="FHIRSERVER"
Set appKey = "/csp/healthshare/fhirserver/fhir/r4"
Set strategyClass = "HS.FHIRServer.Storage.Json.InteractionsStrategy"
set metadataPackages = $lb("hl7.fhir.r4.core@4.0.1")
set importdir="/opt/irisapp/src"
//Install a Foundation namespace and change to it
Do ##class(HS.Util.Installer.Foundation).Install(namespace)
zn namespace

// Install elements that are required for a FHIR-enabled namespace
Do ##class(HS.FHIRServer.Installer).InstallNamespace()

// Install an instance of a FHIR Service into the current namespace
Do ##class(HS.FHIRServer.Installer).InstallInstance(appKey, strategyClass, metadataPackages)

// Configure FHIR Service instance to accept unauthenticated requests
set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint(appKey)
set config = strategy.GetServiceConfigData()
set config.DebugMode = 4
do strategy.SaveServiceConfigData(config)

zw ##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles("/opt/irisapp/fhirdata/", "FHIRSERVER", appKey)

zn "USER"
zpm "load /opt/irisbuild/ -v":1:1
zpm 
load /opt/irisapp/ -v
q
do ##class(Sample.Person).AddTestData()
halt

2. 在 docker-compose.yml 文件中,将 IAM 的镜像更新为最新版本(containers.intersystems.com/intersystems/iam:3.2.1.0-4),因为只有 3.1 以来的 IAM (Kong) 版本才支持 JSON draft-6,而这正是 FHIR 规范所提供的。

讨论 (0)1
登录或注册以继续