08-keycloak-with-other-system

8. keycloak和自研系统的集成

简介

keycloak是一个非常强大的权限认证系统,我们使用keycloak可以方便的实现SSO的功能。虽然keycloak底层使用的wildfly,并且提供了非常方便的Client Adapters和各种服务器进行对接,比如wildfly,tomcat,Jetty等。

之前我们也介绍了keycloak如何通过OpenID Connect和SAML协议和wildfly应用进行集成。虽然集成起来非常方便,但是一切都是一个黑盒子,我们并不知道具体的工作原理,今天我们来点实际的,看下keycloak如何和各类自建的系统进行集成。

接入前的前置准备

在接入各种应用之前,需要在keycloak中做好相应的配置。一般来说需要使用下面的步骤:

  1. 创建新的realm:

一般来说,为了隔离不同类型的系统,我们建议为不同的client创建不同的realm。当然,如果这些client是相关联的,则可以创建在同一个realm中。

  1. 创建新的用户:

用户是用来登录keycloak用的,如果是不同的realm,则需要分别创建用户。

  1. 添加和配置client:

这一步是非常重要的,我们需要根据应用程序的不同,配置不同的root URL,redirect URI等。

还可以配置mapper和scope信息。

最后,如果是服务器端的配置的话,还需要installation的一些信息。

有了这些基本的配置之后,我们就可以准备接入应用程序了。

注意,一般来说我们创建的client protocol是openid-connect,这是因为SAML只适用于web程序,并且比较复杂。

SPA单体页面接入keycloak

如果我们是SPA的单体页面,该怎么接入keycloak呢?

页面接入keycloak需要使用keycloak-js这个js客户端。我们直接在页面上引入这个js客户端即可使用了。

先看一下keycloak-js是怎么创建的:

Keycloak客户端的初始化可以接受4个参数,url表示的是keycloak的server url,realm是我们在第一阶段创建的realm,clientId也是在第一阶段创建client时候填的id,最后一个onLoad参数表示的是加载时候执行的action。

有了keycloak的这些配置之后,我们就是可以对其进行初始化了:

上面代码表示keycloak在初始化的时候首先要去执行login-required操作,也就是说要执行身份认证。

如果没有认证的话将会跳转到keycloak的认证页面。认证完成之后,将会返回auth,表示是否授权成功。

登录成功之后,我们可以通过keycloak对象做很多操作。

比如,登出操作:

获取keycloak的各种属性:

从keycloak中获取用户信息:

更重要的是,有了idToken,就可以使用这个token去和keycloak进行交互,获取更多的信息。

我们看下怎么使用keycloak来更新token:

SpringBoot 接入keycloak

现在java体系中最流行的就是SpringBoot了,如果在一个通用的SpringBoot程序中接入keycloak呢?

keycloak提供了一个Keycloak Spring Boot adapter ,我们可以这样来引用:

这个starter支持SpringBoot底层的这些服务器:Tomcat,Undertow,Jetty。

如果是上面3个服务器的话,不需要额外的配置。

有了依赖包之后,我们需要在SpringBoot的配置文件中配置keycloak的一些基本信息:

先介绍一下上面配置文件中各项的意思。

注意,配置文件中的内容和keycloak中的各项配置是一致的,大家一定要属性keycloak的配置,多修改多运行一下。

配置文件中realm表示的是我们创建的realm名。

auth-server-url是keycloak中认证服务的url。

ssl-required有三个值,分别是none:所有的请求都不使用HTTPS;external:只有外部请求才使用HTTPS,对于本地的访问使用HTTP;all:所有的请求都使用HTTPS。

Resources就是我们在realm中创建的client。

secret是我们创建的client secret。

我们还可以为keycloak配置一些web.xml中出现的权限:

上面的配置表示的是访问/insecure需要admin或者user的权限,访问/admin需要admin的权限。

SpringBoot的Rest服务

有了这些配置,我们基本上就可以创建一个基于spring boot和keycloak的一个rest服务了。

假如我们为keycloak的client创建了新的用户:alice。

第一步我们需要拿到alice的access token,则可以这样操作:

这个命令是直接通过用户名密码的方式去keycloak服务器中拿取access_token,除了access_token,这个命令还会返回refresh_token和session state的信息。

因为是直接和keycloak进行交换,所以keycloak的directAccessGrantsEnabled一定要设置为true。

有小伙伴要问了,上面命令中的Authorization是什么值呢?

这个值是为了防止未授权的client对keycloak服务器的非法访问,所以需要请求客户端提供client-id和对应的client-secret并且以下面的方式进行编码得到的:

access_token是JWT格式的,我们可以简单解密一下上面命令得出的token:

有了access_token,我们就可以根据access_token去做很多事情了。

比如:访问受限的资源:

这里的api/resourcea只是我们本地spring boot应用中一个非常简单的请求资源链接,一切的权限校验工作都会被keycloak拦截,我们看下这个api的实现:

可以看到这个只是一个简单的txt返回,但是因为有keycloak的加持,就变成了一个带权限的资源调用。

上面的access_token解析过后,我们可以看到里面是没有包含权限信息的,我们可以使用access_token来交换一个特殊的RPT的token,这个token里面包含用户的权限信息:

将得出的结果解密之后,看下里面的内容:

可以看到,这个RPT和之前的access_token的区别是这个里面包含了authorization信息。

我们可以将这个RPT的token和之前的access_token一样使用。

使用KeycloakSecurityContext

KeycloakSecurityContext是keycloak的上下文,我们可以从其中获取到AccessToken,IDToken,AuthorizationContext和realm信息。

而在AuthorizationContext中又包含了授权的权限信息。如果能够在程序中获取到KeycloakSecurityContext,则可以进行更精确的程序控制。

那么怎么获取到KeycloakSecurityContext呢?

我们可以直接从request中获取到。

我们看下KeycloakSecurityContext的一些关键方法:

Authorization Client Java API

上面介绍的Spring Boot中的其实是隐藏的做法,adaptor自动为我们做了和Keycloak认证服务连接的事情,如果我们需要手动去处理,则需要用到Authorization Client Java API。

添加maven依赖:

client会去读取meta-info中的keycloak.json信息:

接下看下怎么使用AuthzClient。

创建一个:AuthzClient

获取RPT:

本文已收录于 www.flydean.com

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

最后更新于

这有帮助吗?