Keycloak入门使用第一篇

  • 简介
  • 安装 & 启动服务器
  • 专有名词 & 基本使用
  • 集成Keycloak
  • 理解运行流程
  • Reference

简介

Keycloak 为现代应用和分布式服务提供了一套完整的认证授权管理解决方案,它是开源的,是一个独立的认证授权服务器。它主要是基于OAuth2协议的实现,同时提供了多种语言库,让我们可以很快速地根据我们的需求将Keycloak集成到我们的项目中去使用。

这里主要介绍Keycloak的一些基本使用实践,在学习Keycloak之前,最好要先了解OAuth2的协议流程,否则比较难以理解keycloak的认证过程。在熟悉了OAuth2协议以后去学习Keycloak,其实就很简单了。

若想了解OAuth2协议,可以看这篇 理解OAuth2协议

下面列出的是我所知道的Keycloak相关的内容,下面会详细介绍其中的某一些

  • 是一个独立的认证授权服务器,提供完整的认证授权解决方案
  • 主要基于OpenID-Connect & SAML协议
  • 基本的登录注册,以及登录注册页面主题自定义
  • 很人性化的用户界面管理,比如用户、角色、session、Clients等等的管理
  • 具有独立的数据库,用于存储用户等认证授权数据
  • 支持联合数据存储,比如集成Ldap服务器;提供SPI扩展,比如user Storage SPI,可以让用户的一部分数据存储在你自己的数据库,一部分存储在keycloak自己的数据库
  • 提供多种语言库集成keycloak
  • 提供管理API,用于管理keycloak中所有的认证授权对象
  • Docker-compose一键安装,同时windows解压版解压后即可使用

安装 & 启动服务器

  • 解压版安装
    – 下载地址: https://downloads.jboss.org/keycloak/11.0.3/keycloak-11.0.3.zip
    https://www.keycloak.org/downloads
    – 默认是使用H2数据库存储数据,如果你想要换成其他数据库可以参考:
    https://www.cnblogs.com/ifme/p/12588910.html
    添加链接描述

    解压后可以看到上面的文件目录。
    Keycloak提供多种模式启动,standalone单机启动,domain集群启动。我们这里使用单机启动,进去到bin目录,找到standalone.bat, 双击启动。启动后访问 http://localhost:8080,正常访问说明启动成功,如下:

    点击Administration Console, 第一次需要给admin用户创建密码。
  • docker-compoe安装
    – Docker安装: https://github.com/keycloak/keycloak-containers/tree/master/docker-compose-examples
    安装使用很简单,这里就累述了。

专有名词 & 基本使用

当你启动的keyclaok服务器,然后使用admin账号登录以后,进去到keycloak管理页面:

这是Master Realm的settings页面,Master Realm是keycloak默认有的realm,顾名思义就是用于管理的realm,例如admin这个用户就是属于这个realm:

那Realm是什么意思呢?Realm字面意思是领域,指的是在某一个软件业务领域中所涉及的用户认证授权管理相关的对象,在这个realm下有用户、角色、会话(session)等等用于认证授权管理的对象。

假设一个公司A使用一个ERP系统,那么就可以给这个公司A设置一个Realm,用于该公司所有员工的授权管理。那么如果另一个公司B也使用这个ERP系统(假设这个ERP系统是第三方提供给所有公司使用的一个ERP服务,就需要给公司B也创建一个Realm,用于公司B员工的授权管理。

所以Realm之间的相互隔离的一个业务领域概念。

  • 创建一个Realm

    设置一个名字,然后你就可以给你自己的realm设置各种对象了。比如创建用户,创建一个角色,给用户授予角色等等。
    例如:我创建一个USER的角色,创建一个testuser01用户,然后给这个用户授予USER角色:

    界面使用非常简单,大家探索一下就行了。

集成Keycloak


假设我们有两个web服务器,我们需要使用keycloak来对我们的资源进行保护,只有用户登录以后才能访问到这两个服务器的资源,否则就要跳转到登录页面。所以我们要在两个服务之前加一个gateway层,在这一层对用户请求进行拦截,验证用户是否已经登录(了解OAuth2的话,就知道这里就是验证accessToken),如果没有的话,就要引导用户去到keycloak登录页面,认证以后再跳转回到要访问的页面。

因此,我们已经启动了keycloak服务器,缺少的是怎么将拦截用户请求并验证accessToken这些逻辑加入到我们的应用中。别急,keycloak官方给我们提供了这些库,它把这个东西叫做 adaptor(connector),所以我们只要将这些库安装到我们的项目中就可以为我们的应用实现认证授权。

这里呢,我实践的是给nodejs server集成keycloak认证授权,所以以下介绍的是 Nodejs-keycloak-adaptor.
keycloak-nodejs-adaptor 我也是参考官方的例子去实现的。
另外keycloak官方有一些quickstart的最佳实践,参考:keycloakQuickstart

  • 注册一个client
    第一步首先要在你的realm下注册一个client:

    选择clients,点击create,输入clientId,点击save以后出现该client的settings页面,Access Type选择confidential,Valid Redirect URLs必须要填,这个填入你要集成keycloak的那个web服务器的主页,例如http://localhost:3000/*即可。在OAuth2协议中,redirectURI是必填的,而在keycloak这里,意思是回调的redirectURI必须要match上这里配置的Valid Redirect URLs才可以,否则会报错。
    例如上面填的是http://localhost:3000/*,http://localhost:3000/users就可以match,而http://localhost:3001/users就不会match,就会报错。

点击Save,然后切换到最后一栏installation,拿到client的连接信息:

  • 初始化nodejs项目
  1. 使用npm init初始化一个nodejs项目,加入如下依赖:
 "body-parser": "^1.13.3","cors": "^2.8.1","express": "^4.13.3","express-session": "^1.14.2","jsonwebtoken": "^8.5.1","keycloak-admin": "^1.13.0","keycloak-connect": "11.0.2",

其中keycloak-connect就是集成keycloak的连接库

  1. 新建一个keycloak-config.js,将你的的installation连接信息替换替换对应的属性,例如上面的信息就是:
module.exports = {realm: 'myRealm',authServerUrl: 'http://localhost:8080/auth/',clientId: 'testClient',credentials: {secret: '4434b959-835b-45c9-bed5-607e025e0100'},bearerOnly: false
}

authServerUrl记得最后加上/,这里是一个坑,不加可能报错。以上拿到的连接信息,其实resource就是clientId,对应OAuth2中的clientId和clientSecret(credentials.secret)。所以说,如果你熟悉OAuth2,来到这里很容易就知道看到这就是client必须要有的基本信息。

  1. 新建一个app-express.js (名字随你)

直接贴出全部代码:

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser')
const session = require('express-session')
const KeycloakConnect = require('keycloak-connect')
const keycloakConfig = require('./keycloak-config')
const jwt = require('jsonwebtoken')
const  router = express.Router();// keycloak
const memoryStore = new session.MemoryStore();
const keycloak = new KeycloakConnect({store: memoryStore}, keycloakConfig)const app = express();
app.use(bodyParser.json());app.use(session({secret: 'some secret',resave: false,saveUninitialized: true,store: memoryStore
}));app.use(keycloak.middleware({logout: '/logout',admin: '/'
}));// api settings
router.get('/service/public', (req, res) => {res.json({message: 'public'});
});
router.get('/service/secured', keycloak.protect('realm:USER'), function (req, res) {res.json({message: 'secured'});
});const keycloakProtect = keycloak.protect()
router.get('*', (req, resp, next) => {const originalUrl = req.originalUrlif (originalUrl.indexOf('abc') > -1 || originalUrl === '/' || originalUrl.indexOf('favicon.ico') > -1) {return next()}return keycloakProtect(req, resp, next)
}, (req, resp, next) => {const keycloakToken = req.session['keycloak-token']let userId = 'test'if (keycloakToken) {userId = jwt.decode(JSON.parse(keycloakToken).access_token).preferred_username}const cookiesOption = {maxAge: 1000 * 60 * 60 * 24,httpOnly: false}resp.cookie('user_id', userId, cookiesOption)return next()
})app.use(router)
// static resources
app.use(express.static(path.join(__dirname, '/views')));app.listen(3001, () => {console.log('Started at port 3001');
});

这里是使用express启动一个nodejs server

const keycloak = new KeycloakConnect({store: memoryStore}, keycloakConfig)const app = express();
app.use(bodyParser.json());app.use(session({secret: 'some secret',resave: false,saveUninitialized: true,store: memoryStore
}));app.use(keycloak.middleware({logout: '/logout',admin: '/'
}));

新建KeycloakConnect对象,传进去sessionStore以及keycloakConfig。注意这里keycloak的store使用的是express-session的store,因为认证成功以后keycloak就会将所有的token的信息存储在session中。

最后就是use keycloak提供的中间件,查看这些中间源码你就会知道,这些中间件所做的事情其实就是首先会从session拿出accessToken,然后认证accessToken的有效性等等。

keycloak.protect()

keycloak.protect() 在你的router api中加入这个中间件,就能够对你这个API进行认证保护,后面的代码相信大家一看就明白了,这里不多说。(Talk is cheap, show you the code)

完整代码查看:Github (有些代码没有放出来)
运行项目,访问http://localhost:3000/,可以正常访问;访问http://localhost:3000/work.html,会跳转到登录页面。

理解运行流程

那么对应上面的这个例子呢,可能你确实能成功保护你的资源了,但是我们有必要去理解一下整一个认证过程,这个验证过程其实就是OAuth2的授权码模式:

在第2步,web server将用户导向keycloak server的重定向连接:
http://localhost:8080/auth/realms/myRealm/protocol/openid-connect/auth?client_id=nodejs&state=10abdacb-5e85-4f48-8bf7-b8aedb378567&redirect_uri=http%3A%2F%2Flocalhost%3A3001%2Fwork.html%3Fauth_callback%3D1&scope=openid&response_type=code
可以看到使用的就是OAuth2授权码模式:response_type=code

在第3步中keycloak-server将用户导向回web-server的重定向连接:
http://localhost:3001/work.html?auth_callback=1&state=10abdacb-5e85-4f48-8bf7-b8aedb378567&session_state=3f47f74a-ef0c-4245-b87e-22acae8b08e9&code=281cd9c6-187e-423f-84ee-9419aa4dab7d.3f47f74a-ef0c-4245-b87e-22acae8b08e9.aa9ee788-cbb7-4370-9ed2-6de8b2b510b7

  • 通过debug查看存储在session中的keycloak-token信息:

    返回了三个token:accessToken、refreshToken、idToken
    accessToken 用于每次访问资源服务器时验证用户权限,refreshToken用于在accessToken过期以后可以通过它重新想keycloak-server申请一个新的accessToken,而不需求重新登录。idToken用于识别用户身份,这个OpenID-Connect协议新加入的一个token。

  • 补充
    这个例子是基于express,如果你的node-server是使用Koa的话,官方是没有提供Koa相关connector的,如果有需要可以参考我的github,里面有Koa的keycloak例子。啊哈哈哈哈!!
    Github 代码

后面还有一篇哦 入门第二篇

Reference

https://github.com/keycloak
https://www.keycloak.org/

Keycloak 入门使用第一篇相关推荐

  1. 微信公众号开发入门教程第一篇

    微信公众号开发入门教程第一篇 关键字:微信公众平台开发 作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/ ...

  2. Java小白入门系列 第一篇 写在前面

    2018年8月30日  22:00:17 郑州  多云 Sue Java小白入门系列 第一篇  写在前面 写在前面: 首先声明一下,本人也是正在学Java,并不是多么专业人士,只是最近受老师的启发,所 ...

  3. Java萌新入门的第一篇文章

    这篇文章是为了刚入门或者打算入门的萌新们写的,希望看完后能对Java有个初步认识.以后会不定时更新有关Java的干货,就这些要说的,以上. 先介绍下相关背景,不要觉得枯燥,了解一下很有必要. a.计算 ...

  4. Mendix入门教程第一篇-demo实例

    本篇会建立一个入门实例来讲解mendix的基本功能点,包括建立实体.增加页面及权限配置,后续会对每个组件的详细用法做进一步介绍. Mendix项目开发的时候需要先建立或者导入一个项目,然后这个项目就会 ...

  5. FL studio 20简易入门教程 -- 第一篇 -- 软件介绍与初始化

    软件介绍与初始化 文章目录 软件介绍与初始化 前言 一.素材的加载与导入 1. 初始化声卡 2. 导入软音源 3. 加载音效素材 二.基本使用操作 1.midi键盘连接 2.导入及导出 (1)导入素材 ...

  6. javascript基础入门_javascript基础入门学习第一篇

    今天主要讲述js,在讲述今天的编程知识之前,我们要对C++做一个说明因为一些原因C的知识不做更新了,下面将讲述js的编程知识,首先需要了解的是js是一个脚本语言不是编程语言这两者的区别就是一个需要依附 ...

  7. 小白入门PyTorch | 第一篇:什么是PyTorch?

    什么是PyTorch? 这是一个基于Python的科学计算包,主要分入如下2部分: 使用GPU的功能代替numpy 一个深刻的学习研究平台,提供最大的灵活性和速度 开始学习 Tensors (张量) ...

  8. 一个普通高校学生入门C/C++入门的第一篇博客1.0.1

    我叫张粤,来自陕西科技大学2016级电信学院电子科学与技术专业 选择学习C/C++将来从事编程开发行业成为我在大三的一个重要选择,也许对于像我一样不考研的大三学生来说,在校招中走一份好工作是对家长和对 ...

  9. 怎么用python扒网页?新手入门爬虫第一篇!

    python爬虫网页的基本流程: 首先选取一部分精心挑选的种子URL. 将这些URL放入待抓取URL队列. 从待抓取URL队列中读取待抓取队列的URL,解析DNS,并且得到主机的IP,并将URL对应的 ...

最新文章

  1. java+yeild+sleep_Java并发编程--yield sleep和wait的区别
  2. object dection资源
  3. js 根据所输内容生成助记码
  4. python怎么实现检验_[python skill]利用python实现假设性检验方法
  5. Cpp 对象模型探索 / 静态联编和动态联编
  6. 新建parcel写入数据后,读取数据为null
  7. 数独项目--关键代码展示:
  8. svr公式推导_ML-支持向量:SVM、SVC、SVR、SMO原理推导及实现
  9. Android 使用ContentProvider扫描手机中的图片,仿微信显示本地图片效果
  10. 高中电子技术——电弧抑制电路
  11. golang 建立web服务器 http包源码详解
  12. 怎样下载企业通讯录Excel模板
  13. 简单介绍会计师事务所
  14. 《设计模式》(精华集)
  15. MySQL高级-(存储引擎、索引、锁)
  16. 计算机专业教师资格证考什么科目,教师资格证考试科目
  17. 离岸人民币和跨境人民币收款业务
  18. ABCD过桥题的规律
  19. python 素数库_使用Python判断质数(素数)的简单方法讲解
  20. Android设备的序列号与ro.serialno

热门文章

  1. vue全面介绍--全家桶、项目实例
  2. #AE实现矢量数据的基本操作—属性表操作(IFeatureClass)
  3. easyx的基本使用(万字解析)
  4. 6s模型c语言,6S模型.doc
  5. Python菜鸟------七段数码管绘制
  6. office2007安装失败2902_office2007安装失败怎么办?office2007安装失败的解决方法
  7. 用amd组装高档游戏型计算机,开学纳新要理智,DIY一台心仪电脑不求人
  8. python项目运行,导致内存越来越大的原因分析
  9. 为什么Python多线程反而更慢了?
  10. 解析json自动生成表格