Please enable Javascript to view the contents

Keycloak-配置gatekeeper保护没有认证授权的应用功能

 ·  ☕ 5 分钟

重要

虽然louketo-proxy停止开发,转向oauth2proxy。但由于oauth2proxy功能太弱。不适用此场景。继续选用louketo-proxy实现。

部署配置, 一共有三个组件(以nuclio举例):

  1. keycloak: 提供oauth2的认证源。在此处配置client、redirect_url、scope等
  2. louketo-proxy: 作为proxy,代理所有走向nuclio的流量。与keycloak集成,没有权限的请求将被proxy拦截。
  3. nuclio: 没有登录、授权的应用(一种faas平台)。

环境说明

keycloak: 10.0.2

louketo-proxy: v2.3.0

nuclio: 1.5.12

安装

louketo-proxy启动的ingress地址对用户开放,名字应为proxy后面服务的真实地址,如代理proxy服务,则需设置为faas.icos.city

1. 配置louketo-proxy

  • client-id: 配置为keycloak服务中创建的client-name

  • client-secret: 配置为keycloak服务中创建的client, 点击credentials获取。

  • discovery-url: 注意修改keycloak地址和realm名。<keycloak-address>/auth/realms/<realm-name>

  • redirection-url: 认证完成后,返回的访问地址,即louketo-proxy的ingress地址。注意,不带oauth/callback

  • upstream-url: louketo-proxy 后面的真实应用地址。

  • enable-refresh-tokens: 允许refresh-token刷新token。

    用户访问应用,会重定向到Keycloak。 那里获得授权代码。 前端louketo-proxy将此授权代码交换为access tokenrefresh token
    这些token放在前端的cookie中。 当使用过期的access token调用后端时,refresh token将被解密并用于获取新的access token
    refresh token可以过期或无效。 当返回401时,前端应刷新页面,以便将用户重定向到Keycloak。
    更安全的做法是将token存储在redis中, 而不是存储在前端Cookie中。

  • skip-upstream-tls-verify: 跳过证书校验

  • skip-openid-provider-tls-verify: 跳过证书校验

proxy的chart value.yaml如下:(proxy-chart文件)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#【----------------全局变量--------------------】
global:
  #  # 镜像仓库名称
  imageRepositoryName: reg.chebai.org

#【----------------镜像配置--------------------】
# 镜像
imageRepository: paas/louketo-proxy
  #版本要求3位数,不写默认从.Chart.appVersion拿
#imageTag: 5.6.10
  # 拉取镜像策略
imagePullPolicy: Always

#容器启动命令和参数
containersCommand: {}
containersArgs: '[
  "--client-id=<client-id>",
  "--client-secret=<client-secret>",
  "--discovery-url=<keycloak-address>/auth/realms/<realm-name>",
  "--enable-default-deny=true",
  "--secure-cookie=false",
  "--encryption-key=AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j",
  "--enable-json-logging=true",
  "--enable-logging=true",
  "--enable-request-id=true",
  "--enable-security-filter=true",
  "--http-only-cookie=true",
  "--listen=0.0.0.0:8080",
  "--preserve-host=true",
  "--enable-logging",
  "--redirection-url=http://faas.example.com",
  "--upstream-url=http://nuclio-dashboard:8070",
  "--skip-openid-provider-tls-verify",
  "--skip-upstream-tls-verify",
  "--resources=uri=/*|methods=GET,POST,DELETE,PUT,HEAD|roles=nuclio:viewer"
  ]'

#【----------------服务配置--------------------】
#是否启动服务
serviceEnabled: true
  # 服务映射端口类型ClusterIP、NodePort
serviceType: NodePort
  # 服务
serviceName: nuclio-proxy
servicePorts:
# 容器内端口
- port: 8080
  protocol: "TCP"

ingressEnabled: true
ingressAnnotations:
  kubernetes.io/ingress.class: nginx

ingressAddns: false

ingressHosts:
- host: faas
  domain: example.com
  paths:
  - path: /
    servicePort: 8080

2. 配置keycloak

  1. 配置client

  2. 配置Scope

    也可以直接通过Mappers配置audience, ClientScope只是多封装了一层,好处是便于多个client共用。

    2.1 选择icosrealm – 点击Client Scopes – 点击Settings

    • name: 设置名字为nuclio-service
  • Protocol: 设置名字为openid-connect

    2.2 在Client Scope页面 – 点击Mappers

    • name: 设置名字为nuclio-audience
    • Mapper Type: 设置为Audience
    • Included Client: 输入nuclio,选择所要关联的client
    • Add to access token: 将状态设置为ON

    2.3 返回Clients页面 – 点击nuclio client – 选择Client Scopes标签页 – 选择Setup

    Available Client Scopes 中选择刚创建的nuclio-service – 点击Add selected

  1. 创建用户

并将

3. 部署nuclio

nuclio的集群外部访问都删除,比如ingressnodeport等,用户只能通过代理访问nuclio-dashboard:8070服务。

使用

遇到问题

  1. error redirect_url报错:

keycloak-client配置redirect_url 缺少oauth/callback,导致出现报错(keycloak端报错)

  • keycloak中需要设置为http://<nuclio.acme.com>/oauth/callback(也可以直接使用通配符,配置为http://<nuclio.acme.com>/*
  • louketo-proxy启动时配置为http://<nuclio.acme.com>/
  1. 登录成功,但由于未配置audience字段aud,claim中的字段无法对应
    导致如下报错(louketo-proxy 端报错)
1
 'aud' claim and 'client_id' do not match
  1. 使用镜像supervisor启动,导致针对role的鉴权一直失败。

换成reg.chebai.org/paas/louketo-proxy:v1.0.0之后一切正常。

  1. keycloak服务端,注销session,需要重新无痕模式打开新的窗口生效。

过期时间在生成accessToken时被服务端根据配置生成(服务端默认5分钟过期),并保存在cookie中。
在无refreshToken干预的条件下,只有等过期时间(默认5分钟)结束才会过期,返回keycloak登录页面。

  1. nuclio会在请求header中x-nuclio-project-namespace: <namespace: eg. nuclio>,来区分不同命名空间下的function, 后期可以结合User Group,来进行租户划分和授权管理。

后续

nuclio使用louketo-proxy进行鉴权,多租户管理。

Reference

gatekeeper git 仓库

gatekeeper 用户手册

Keycloak-gatekeeper: ‘aud’ claim and ‘client_id’ do not match

Keycloak 文档 - Audience support

参考,理解类似gatekeepr、oauth2proxy这类工具的实现

Open Policy Agent 文档

分享

Hex
作者
Hex
CloudNative Developer

目录