Keycloak快速上手指南,只需10分鐘即可接入Spring Boot/Vue前後端分離應用實現SSO單點登入
阿新 • • 發佈:2020-06-02
登入及身份認證是現代web應用最基本的功能之一,對於企業內部的系統,多個系統往往希望有一套SSO服務對企業使用者的登入及身份認證進行統一的管理,提升使用者同時使用多個系統的體驗,Keycloak正是為此種場景而生。本文將簡明的介紹Keycloak的安裝、使用,並給出目前較流行的前後端分離應用如何快速接入Keycloak的示例。
## Keycloak是什麼
> Keycloak是一種面向現代應用和服務的開源IAM(身份識別與訪問管理)解決方案
Keycloak提供了單點登入(SSO)功能,支援`OpenID Connect`、`OAuth 2.0`、`SAML 2.0`標準協議,擁有簡單易用的管理控制檯,並提供對LDAP、Active Directory以及Github、Google等社交賬號登入的支援,做到了非常簡單的開箱即用。
## Keycloak常用核心概念介紹
首先通過官方的一張圖來了解下整體的核心概念
![keycloak-core-concepts](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224154219-1670568728.png)
這裡先只介紹4個最常用的核心概念:
1. `Users`: 使用者,使用並需要登入系統的物件
2. `Roles`: 角色,用來對使用者的許可權進行管理
3. `Clients`: 客戶端,需要接入Keycloak並被Keycloak保護的應用和服務
4. `Realms`: 領域,領域管理著一批使用者、證書、角色、組等,一個使用者只能屬於並且能登陸到一個域,域之間是互相獨立隔離的, 一個域只能管理它下面所屬的使用者
## Keycloak服務安裝及配置
### 安裝Keycloak
Keycloak安裝有多種方式,這裡使用Docker進行快速安裝
```bash
docker run -d --name keycloak \
-p 8080:8080 \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=admin \
jboss/keycloak:10.0.0
```
訪問[http://localhost:8080](http://localhost:8080/auth/)並點選Administration Console進行登入
![keycloak-web-home](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224240204-1053411340.png)
### 建立Realm
建立一個新的realm: demo,後續所有的客戶端、使用者、角色等都在此realm中建立
![keycloak-web-add-realm-1](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224309580-1049199853.png)
![keycloak-web-add-realm-2](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224342775-1336241797.png)
![keycloak-web-add-realm-3](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224412221-1766145312.png)
### 建立客戶端
#### 建立前端應用客戶端
建立一個新的客戶端:vue-demo,Access Type選擇public
![keycloak-web-add-client-1](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224437648-1277789621.png)
#### 建立後端應用客戶端
建立一個新的客戶端:spring-boot-demo,Access Type選擇bearer-only
![keycloak-web-add-client-2](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224457758-1733906136.png)
儲存之後,會出現Credentials的Tab,記錄下這裡的secret,後面要用到
![keycloak-web-add-client-3](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224528568-538640826.png)
### 關於客戶端的訪問型別(Access Type)
上面建立的2個客戶端的訪問型別分別是public、bearer-only,那麼為什麼分別選擇這種型別,實際不同的訪問型別有什麼區別呢?
事實上,Keycloak目前的訪問型別共有3種:
`confidential`:適用於服務端應用,且需要瀏覽器登入以及需要通過金鑰獲取`access token`的場景。典型的使用場景就是服務端渲染的web系統。
`public`:適用於客戶端應用,且需要瀏覽器登入的場景。典型的使用場景就是前端web系統,包括採用vue、react實現的前端專案等。
`bearer-only`:適用於服務端應用,不需要瀏覽器登入,只允許使用`bearer token`請求的場景。典型的使用場景就是restful api。
### 建立使用者和角色
#### 建立角色
建立2個角色:ROLE_ADMIN、ROLE_CUSTOMER
![keycloak-web-add-role](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224558590-550749891.png)
#### 建立使用者
建立2個使用者:admin、customer
![keycloak-web-add-user](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224629683-642650639.png)
#### 繫結使用者和角色
##### 給admin使用者分配角色ROLE_ADMIN
![keycloak-web-add-user-role-1](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224654354-1044835996.png)
##### 給customer使用者分配角色ROLE_CUSTOMER
![keycloak-web-add-user-role-2](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224710348-811223267.png)
## Vue應用整合Keycloak簡明指南
### 建立vue專案
```bash
vue create vue-demo
```
### 新增官方Keycloak js介面卡
```bash
npm i keycloak-js --save
npm i axios --save
```
### main.js
```javascript
import Vue from 'vue'
import App from './App.vue'
import Keycloak from 'keycloak-js'
Vue.config.productionTip = false
// keycloak init options
const initOptions = {
url: 'http://127.0.0.1:8080/auth',
realm: 'demo',
clientId: 'vue-demo',
onLoad:'login-required'
}
const keycloak = Keycloak(initOptions)
keycloak.init({ onLoad: initOptions.onLoad, promiseType: 'native' }).then((authenticated) =>{
if(!authenticated) {
window.location.reload();
} else {
Vue.prototype.$keycloak = keycloak
console.log('Authenticated')
}
new Vue({
render: h => h(App),
}).$mount('#app')
setInterval(() =>{
keycloak.updateToken(70).then((refreshed)=>{
if (refreshed) {
console.log('Token refreshed');
} else {
console.log('Token not refreshed, valid for '
+ Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');
}
}).catch(error => {
console.log('Failed to refresh token', error)
})
}, 60000)
}).catch(error => {
console.log('Authenticated Failed', error)
})
```
### HelloWorld.vue
```vue
```
`getAdmin()`及`getCustomer()`這2個方法內部分別請求restful api
## Spring Boot應用整合Keycloak簡明指南
### 新增Keycloak Maven依賴
```xml
```
### Spring Boot配置檔案
官方文件及網上大部分示例使用的都是properties格式的配置檔案,而yaml格式的配置檔案相對更簡潔清晰些,此示例使用yaml格式的配置檔案,內容如下
```yaml
server:
port: 8082
keycloak:
realm: demo
auth-server-url: http://127.0.0.1:8080/auth
resource: spring-boot-demo
ssl-required: external
credentials:
secret: 2d2ab498-7af9-48c0-89a3-5eec929e462b
bearer-only: true
use-resource-role-mappings: false
cors: true
security-constraints:
- authRoles:
- ROLE_CUSTOMER
securityCollections:
- name: customer
patterns:
- /customer
- authRoles:
- ROLE_ADMIN
securityCollections:
- name: admin
patterns:
- /admin
```
除了幾個必填的配置項外,另外需要注意的幾個配置項如下
`credentials.secret`:上文新增客戶端後Credentials Tab內對應的內容
`bearer-only`:設定為true,表示此應用的Keycloak訪問型別是bearer-only
`cors`:設定為true表示允許跨域訪問
`security-constraints`:主要是針對不同的路徑定義角色以達到許可權管理的目的
* `/customer`:只允許擁有`ROLE_CUSTOMER`角色的使用者才能訪問
* `/admin`:只允許擁有`ROLE_ADMIN`角色的使用者才能訪問
* 未配置的路徑表示公開訪問
### Controller內容
```bash
@RestController
public class HomeController {
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/customer")
public String customer() {
return "only customer can see";
}
@RequestMapping("/admin")
public String admin() {
return "only admin cas see";
}
}
```
## 專案效果演示
分別啟動前後端專案後,本地8081埠對應vue前端專案,本地8082埠對應Spring Boot實現的restful api專案
### 首次訪問vue前端專案
第一次訪問vue專案會跳轉Keycloak登入頁
![keycloak-demo-1](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224749080-1538898427.png)
### 登入admin使用者
![keycloak-demo-2](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224807766-727425878.png)
### 登入customer使用者
![keycloak-demo-3](https://img2020.cnblogs.com/blog/2017272/202005/2017272-20200528224830724-264458676.png)
## 總結
Keycloak部署及接入簡單,輕量的同時功能又不失強大,非常適合企業內部的SSO方案。
本文示例專案地址:[keycloak-demo](https://github.com/vigozhang/keyclo