keycloak流水账
1、介绍
最近的两个项目中均使用了keycloak来实现sso,记录一下。
Keycloak 是一款由 Red Hat(红帽) 主导开发并维护的开源身份认证与访问管理(IAM,Identity and Access Management)工具,核心目标是为应用程序(Web 应用、移动应用、API 服务等)提供统一、安全、标准化的用户身份验证、授权和用户管理能力,避免开发者重复开发身份相关功能。
所谓身份认证跟访问控制,简单来说就是登录跟权限管理,我们项目中主要是用来实现sso,权限用独立服务实现。
2、下载与启动
keycloak中文网:https://keycloak.com.cn/
github地址:https://github.com/keycloak/keycloak
可以从官网下载,如果需要较早的历史版本,可以从github下载。jdk8对应的最新版本为16.1.1,目前大概在github的第8页:

解压后目录结构:

目录介绍:
keycloak-16.1.1/
├── bin/ # 启动脚本与工具
├── docs/ # 文档与示例
├── domain/ # 域模式配置(多服务器集群)
├── standalone/ # 独立模式配置与数据
├── modules/ # 模块化依赖库
├── themes/ # 主题文件
├── welcome-content/ # 默认欢迎页面资源
修改数据库配置文件standalone/configuration/standalone.xml,默认为h2数据库,以改为本地mysql为例(需要准备数据库并配置schema):

修改配置文件后,需要再添加mysql驱动:在keycloak-16.1.0/modules/system/layers/keycloak/com目录创建mysql/main目录,并在其中放入mysql驱动及驱动说明文件module.xml,modele.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<module name="com.mysql" xmlns="urn:jboss:module:1.9">
<resources>
<resource-root path="mysql-connector-java-8.0.27.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
修改后,keycloak-16.1.0/modules/system/layers/keycloak/com目录内容如下:

直接执行 bin/standalone.sh 即可启动服务,windows环境为bin/standalone.bat
启动无异常,看到如下结果则为启动成功

首次访问http://localhost:8080/auth,会要求输入管理员账号

创建管理员后,点击Administration Console即可登录keycloak

3、主要功能介绍
几个主要概念的解释
Realm: 领域,可以理解为租户的概念,用于数据隔离;连接同一个realm的客户端即可实现sso;
client:客户端,第三方系统要连接的处理单元,用于对不同协议的支持;多个协议要配多个客户端;
User Federation: 用户融合,一般用于对外部系统用户的校验处理;
Authentication: 认证流程,配置当前领域的认证流程,可以配多个,每个client关联自己需要的流程;
User: 用户,keycloak自己管理的用户;
Group:用户组,用于对用户的分组管理;
keycloak本身用户\用户组\角色的使用比较简单,可以自行操作一测试一下,不过多介绍。
很多时候,我们并不是直接用keycloak的原生功能来做权限管控,而是借助keycloak的功能来实现自己的用户认证跟权限管控。这就涉及到插件的开发,官方提供了丰富的插件示例,github地址为:https://github.com/keycloak/keycloak-quickstarts, 使用中注意插件版本跟keycloak版本保持一致。
功能介绍到此为止,具体使用放在示例中进行说明。
4、示例场景
一般来说,keycloak我们不是拿过来直接使用,而是要根据具体要求做一些修改适配。
场景1:不需要keycloak的用户管理,我们可能有自己独立的用户系统,需要接入我们自己的用户系统做登录校验;
场景2:keycloak的登录只有用户、密码,我们可能需要一些其它的属性,例如租户、验证码等;
对于场景1,我们需要修改user-storage-simple部分,然后配合User Federation功能使用;对于场景2,我们需要修改action-token-authenticator部分,配合Authentication自定义认证流程使用。
当然,更多的场景可能是1+2;以下就以1+2为例,做使用说明:
4.1 主题修改
既然有自定义属性,默认的登录页面肯定是不符合要求的了。keycloak提供了自定义主题方式,位置在Realm Settings -- Themes中,LoginTheme 即为我们看到的登录页面主题;对应于themes目录内容;

主题采用ftl模版编写,base为不带任何样式的原生主题,keycloak为官方默认主题;如果需要自定义主题,可以复制base(或者keycloak)目录,重命名为想要的主题名称,然后进行修改;
注意:如果有ftl或者css文件修改,一定要复制到自定义主题目录进行修改,而不是修改原有文件
4.2 添加自定义属性及认证流程
自定义属性在Clients--you client--Mapper中添加, Mapper Type选择User Attribute,如果你想把属性添加到jwt中,注意下方Add to access token选择开启。

自定义认证器需要修改keycloak插件action-token-authenticator,本例中将租户、账号的验证均采用第三方接口方式,认证器中直接调用,跳过用户融合方式。
public class MyCustomAuthenticator implements Authenticator {
@Override
public void authenticate(AuthenticationFlowContext context) {
UserModel user = context.getAuthenticationSession().getAuthenticatedUser();
if (user != null) {
context.setUser(user);
context.success();
return;
}
// 只挑战客户端以显示登录表单,不在此处读取任何参数
Response challenge = context.form().createLoginUsernamePassword();
context.challenge(challenge);
}
@Override
public void action(AuthenticationFlowContext context) {
// 认证过程
}
}
action-token-authenticator打包后放到keycloak目录的providers目录下,默认该目录不存在,需要新建;

action-token-authenticator.jar 放到provicers目录后,默认是不生效的。需要配置自定义认证流程。
Authentication默认流程为Browser,点击右边copy,名称重命名为my-auth-flow; 在流程中添加我们自定义的认证器

名称就是action-token-authenticator插件中自定义认证器的类名

最重要的,调整顺序,理清楚哪些需要开启,哪些不需要,具体场景不同,配置也不同, 这里只是给出一个示例,并不是正确配置

配置的认证流程,要在client启用才会真正生效。在client的settings-Authentication Flow Overrides下的Browser Flow 选择上面配置的自定义认证流程
这样,一个自定义认证流程便生效了。
4.3 client配置
client的配置主要关注以下几项:
Client Protocol : 客户端协议,一般选择openid-connect,也就是OIDC
Access Type : 如果前端连接,选择public,如果后端连接,选择confidential或者bearer-only均可,如果是客户端用户\密码登录方式,选择confidential即可;
Valid Redirect URIs: keycloak允许的回调地址,配置客户端地址即可,注意要加通配符;
Web Origins:跨域地址,不需要通配符;
5、前后端如何使用
后端有spring-boot-keycloak依赖,前端有keycloak-js,注意版本与keycloak保持一致。
# 添加依赖
npm add keycloak-js@16.1.1
npm install
示例配置

后端暂略..
事情并没有结束,后续还有token解析、有效期、token更换....一并暂略
浙公网安备 33010602011771号