本文介绍如何使用自建的Keycloak作为IdP来提供身份服务,实现网格内应用的单点登录。网格内应用无需实现认证、鉴权逻辑,通过配置ASM的自定义授权服务,即可通过OIDC协议使用Keycloak完成单点登录。鉴权通过后,请求将携带Keycloak中的用户信息一同发往应用。
前提条件
已创建ASM实例。具体操作,请参见创建ASM实例。
已创建Kubernetes托管版集群。具体操作,请参见创建Kubernetes托管版集群。
已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。
已为default命名空间启用Sidecar自动注入。具体操作,请参见启用自动注入。
相关概念
概念 | 说明 |
IdP | Identity Provider的缩写,身份提供商。例如,您可以通过账号+密码的形式来验证您的身份。当您使用支付宝账号登录优酷,这个场景中支付宝即为IdP。 |
OIDC | OIDC是OpenID Connect的简称,是一个基于OAuth 2.0协议的身份认证标准协议。更多信息,请参见OpenID Connect。 |
Scope | OIDC中的概念,每一个IdP同时也保存了用户的各种信息,例如Email、个人资料等,这些分类被称为Scope。在通过IdP进行Authentication(登录操作)时,一些IdP会要求选择允许访问用户的哪些资料,每一个类别都对应一个Scope。 |
操作步骤
步骤一: 部署演示应用和Keycloak
参照下方YAML,使用kubectl apply -n default -f xxx.yaml命令,将Httpbin应用部署至ACK集群的default命名空间。
参照下方YAML,使用kubectl apply -n default -f xxx.yaml命令,将Keycloak应用部署至ACK集群的default命名空间。
步骤二:将演示应用和Keycloak通过ASM网关暴露至公网
本文示例使用HTTPS(端口:443)访问演示应用,使用HTTP(端口:80)访问Keycloak控制台。
为HTTPS服务创建证书,命名为myexample-credential。更多内容,请参见通过ASM网关启用HTTPS安全服务。
使用如下YAML在ASM集群创建网关规则和虚拟服务,将Keycloak露出在公网。
使用http://${入口网关地址}在浏览器访问Keycloak应用。
单击Administration Console,使用部署Keycloak时指定的Admin和PassWord进行登录。
步骤三:配置Keycloak
在Keycloak左侧导航栏,在Master下拉列表中单击Create Realm。
在新建Realm配置导航页面,如下图所示,创建新的Client。
创建完成后,在Realm页面,按照下图,创建User。单击Save。
在User details页面,单击Credentials。
在弹出的对话框,设置登录密码。单击Save。
参照下图,创建一个Realm Role。单击Save。
在User details页面,选择Role mapping。
在Role mapping页面,单击Assign role。将步骤六创建的Role分配给当前用户。
参照下图,创建Client Scope。单击Save。
在Client Scope页面,单击mappers,参照下图,添加一个Mapper。单击Save。
单击scope,选中步骤六创建的Role左侧的复选框,单击Assign。
在Client设置界面,单击client scope,以default方式添加client scope。
按照下图,添加集群oauth2-proxy的Valid redirect URls。单击Save。
该操作步骤的示例里只有Keycloak服务使用HTTP协议,其余服务均使用HTTPS。所以redirect URI的格式为:https://${您的ASM网关地址}/oauth2/callback。
至此,Keycloak已经全部设置好。您需要记录以下信息:
新建Realm的ID:Test-oidc。
Realm中创建的Client ID:oauth2proxy。
Client设置中,Credentials子选项卡中的client secret。
步骤四:启用ASM自定义授权,配置OIDC单点登录
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在自定义授权服务页面,单击关联自定义授权服务,选择OIDC身份认证授权服务。设置OIDC身份认证授权服务参数,单击创建。
请您根据之前创建的OIDC应用的相关信息,填写如上图中的字段,您可以使用ASM网关作为登录重定向地址。更多关于Cookie Secret,请参见Cookie Secret的生成。
IdP OIDC Issuer URL:http://${ASM网关地址}/realms/${keycloak中创建的realm}。
ClientID、Client Secret:使用上一步骤中记录的参数。
Scopes:该参数中的OpenID为必填项,请您根据实际情况进行填写。
参照如下示例,创建VirtualService。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: oauth2-vs namespace: istio-system spec: gateways: - ingressgateway hosts: - '*' http: - match: - uri: prefix: /oauth2 name: oauth2 route: - destination: host: asm-oauth2proxy-httpextauth-oidc.istio-system.svc.cluster.local port: number: 4180
说明route字段的host请您替换为您的ACK集群中istio-system namespace下对应的Oauth2Proxy的Service名称。
为防止VirtualService冲突,请避免其他VirtualService匹配前缀为《/oauth2》的路径。
步骤五:创建授权策略
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在授权策略详情页面,单击使用YAML创建。
在创建页面,选择命名空间和场景模版,配置如下YAML文件,然后单击创建。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: oidc namespace: istio-system spec: action: CUSTOM provider: name: httpextauth-oidc rules: - to: - operation: notPorts: - '80' selector: matchLabels: istio: ingressgateway
说明AuthorizationPolicy指定了访问除了80以外的其它端口,均需要进行授权。
provider name填写您关联的自定义授权服务的名称,您可以在自定义授权服务的列表中进行查找。
步骤六:验证
在浏览器中访问${ASM网关外部IP:80}。
预期结果:若您可以看到如上页面,则证明单点登录已经生效。
单击Sign in with OpenID Connect,在Keycloak的登录页面,请输入您在步骤一中创建的测试账号以及密码,单击登录。
预期结果:
单击Request inspection,选择 。
预期结果:
请将上一步骤中Bearer之后请求携带的JWT在JWT Debugger中进行解析。更多关于JWT Debugger的内容,请参见JWT debugger。
预期结果:解析成功后,您可以看到如下信息。其中附带Keycloak中存储的用户信息,并且当前的JWT已经经过了ASM的校验。