keycloak+istio实现基于jwt的服务认证授权

envoy rbac介绍

基于角色的访问控制(RBAC)为服务提供服务级别和方法级别的访问控制。RBAC政策是附加的。依次检查策略。根据操作以及是否找到匹配的策略,允许或拒绝请求。

策略配置主要包括两个部分。

  • permissions

由AuthorizationPolicy中to转换过来

定义角色的权限集。 每个权限都与OR语义匹配。 为了匹配此策略的所有操作,应使用any字段设置为true的单个Permission。
  • principals

由AuthorizationPolicy中to和when字段转换过来

根据操作分配/拒绝角色的主体集。 每个主体都与OR语义匹配。 为了匹配此策略的所有下游,应使用any字段设置为true的单个Principal。

本文将基于istio和keyclock应用envoy的rbac策略,实现基于jwt的权限控制。

启动keycloak

docker run -d  -p 8443:8443 -p 80:8080 -e PROXY_ADDRESS_FORWARDING=true  -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:11.0.0

配置keycloak

创建istioclient

创建clientrole

分配role

创建rolemapper,如果不创建信息会保存在resource_access.istio.roles,但是istio的jwt auth无法获取子路径下的信息,需要将信息映射出来

安装服务

kubectl create ns foo
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo

为ingressgate配置认证策略

为服务httpbin创建Gateway

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
  namespace: foo
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
EOF

创建vs

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
  namespace: foo
spec:
  hosts:
  - "*"
  gateways:
  - httpbin-gateway
  http:
  - route:
    - destination:
        port:
          number: 8000
        host: httpbin.foo.svc.cluster.local
EOF

应用授权策略,只有通过认证的服务才能访问

kubectl apply -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
  name: "jwt-example"
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  jwtRules:
  - issuer: "http://192.168.8.10/auth/realms/master"
    jwksUri: "http://192.168.8.10/auth/realms/master/protocol/openid-connect/certs"
EOF

测试访问

获取token

export TOKEN=`curl -s -d "audience=master" -d "client_secret=69ae93e2-4b41-4a20-a9de-1f472b0ca2a9" -d "client_id=istio" -d "grant_type=client_credentials" http://192.168.8.10/auth/realms/master/protocol/openid-connect/token | jq -r ".access_token"`

curl "http://ingress-gateway-ip:8080/headers"  -H "Authorization: Bearer $TOKEN"

可以正常访问

使用jwt对特定路径进行认证授权

应用以下策略在GET/POST时判断headers时验证客户端是否具有fuckistio角色,

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-jwt
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  action: ALLOW
  rules:
  - from:
    - source:
        requestPrincipals: ["*"]
    to:
    - operation:
        paths: ["/headers"]
        methods: ["POST"]
    when:
    - key: request.auth.claims[roles]
      values: ["fuckistio"]
  - from:
    - source:
        notRequestPrincipals: ["*"]
    to:
    - operation:
        paths: ["/headers"]
        methods: ["GET"]
  - from: # 由于envoy中当有allow条件时,如果无法匹配默认会拒绝所以需要应用以下策略在访问非headers时不验证客户端信息
    - source:
        notRequestPrincipals: ["*"]
    to:
    - operation:
        notPaths: ["/headers"]
EOF

验证

尝试请求/headers POST method,可以访问,但是需要添加token

[root@centos /]# curl -XPOST "http://httpbin.foo:8000/headers"
RBAC: access denied
[root@centos /]# curl -XPOST "http://httpbin.foo:8000/headers"  -H "Authorization: Bearer $TOKEN"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>

get /headers 无需认证即可访问

[root@centos /]#  curl  "http://httpbin.foo:8000/headers"
{
  "headers": {
    "Accept": "*/*",
    "Content-Length": "0",
    "Host": "httpbin.foo:8000",
    "User-Agent": "curl/7.29.0",
    "X-B3-Sampled": "1",
    "X-B3-Spanid": "81d7413f45dd1e9e",
    "X-B3-Traceid": "18a755df138a124a81d7413f45dd1e9e"
  }
}

ip 接口无需认证即可使用访问任意方法访问

[root@centos /]# curl -XPOST "http://httpbin.foo:8000/ip"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>
[root@centos /]# curl "http://httpbin.foo:8000/ip"
{
  "origin": "127.0.0.1"
}

总结

使用keycloak结合istio可以实现细粒度的认证授权策略,客户端只需要到认证授权中心获取token,服务端无需关心任何认证授权细节,专注以业务实现,实现业务逻辑与基础设施的解耦

参考
https://www.doag.org/formes/pubfiles/11143470/2019-NN-Sebastien_Blanc-Easily_Secure_your_Microservices_with_Keycloak-Praesentation.pdf
https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/jwt_authn/v3/config.proto
https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter#config-http-filters-jwt-authn

扫描关注我:

微信

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么使用istio:云平台令使用它们的公司受益匪浅。但不可否认的是,上云会给 DevOps 团队带来压力。为了可移植性,开发人员必须使用微服务来构建应用,同时运维人员也正在管理着极端庞大的混合云和多云的部署环境。 Istio 允许您连接、保护、控制和观察服务。从较高的层面来说,Istio 有助于降低这些部署的复杂性,并减轻开发团队的压力。它是一个完全开源的服务网格,作为透明的一层接入到现有的分布式应用程序里。它也是一个平台,拥有可以集成任何日志、遥测和策略系统的 API 接口。Istio 多样化的特性使您能够成功且高效地运行分布式微服务架构,并提供保护、连接和监控微服务的统一方法。教学内容:istio原理,envoy原理,envoy案例,envoy配置,istio crd配置,istio流量管理,istio安全配置,istio可观察性,istio策略控制,istio升级,istio常见问题,istio wasm,istio多控制面板,gateway-api,slime教学特色:a.1000多个istio实战案例,20多个envoy案例。800多个envoyfilter案例,全程已实战为主,理论相对较少,案例90%可试验b.涵盖98%以上crd字段配置c.不仅讲解yaml配置,同时结合envoy配置讲解d.不回避难点内容,深入讲解envoyfilter配置e深入讲解envoyf详细讲解额外内容,比如gateway-api,wasm,升降级,发布,灰度发布,蓝绿发布,istioctl命令,slime,多控制面板,多集群,常见问题g以一个完整案例串联所有内容h以markdown文件提供课件,内容详细,方便大家练习I有学员指出我的istio课程不够突出重点,安装80/20原则,20%内容是常用的,那我是否就讲这20%就可以了呢,其他课程确实是这么干的,他们只讲擅长的20%,我的目的不是这样的,我希望istio课程买我的一个就够了,让你全面学习istio,甚至遇到偏的问题不需要百度,课程里就有讲过,但是难免会出现一个问题,就是不够突出重点,我尽量兼顾全面的时候突出重点,讲到重点,核心功能时我会提示下。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值