登录和身份认证是现代Web最基本的功能之一应用程序。对于企业内部系统,多个系统往往希望有一套SSO服务,统一管理企业用户的登录和身份认证,以提高同时使用多个系统的用户体验。Keycloak就是为这种场景而生的。本文将简要介绍Keycloak的安装和使用,并针对目前流行的前后端分离应用举例说明如何快速接入Keycloak。什么是钥匙斗篷?Keycloak是一种用于现代应用程序和服务的开源IAM(身份识别和访问管理)解决方案。Keycloak提供单点登录(SSO)功能,支持OpenIDConnect、OAuth2.0、SAML2.0标准协议。它还支持使用LDAP、ActiveDirectory以及Github和Google等社交帐户登录,开箱即用,使用起来非常简单。Keycloak常用核心概念介绍。首先用一张官方图片来理解整体的核心概念。这里只介绍四个最常用的核心概念:Users:用户,使用和需要登录系统的对象Roles:角色,用于用户Clients:需要访问Keycloak的客户端,应用程序和服务受Keycloak保护Realms:Realms,管理着一批用户、证书、角色、组等。一个用户只能属于并只能登录一个域,域之间是相互独立和隔离的。一个域只能管理其下的用户。Keycloak服务安装和配置。有很多方法可以安装Keycloak。这里使用Docker来实现快速安装。8080:8080\-eKEYCLOAK_USER=admin\-eKEYCLOAK_PASSWORD=admin\jboss/keycloak:10.0.0访问http://localhost:8080点击AdministrationConsole登录CreateRealm新建realm:demo,关注所有Clients,用户,角色等都是在这个realm中创建创建客户端创建前端应用客户端创建新客户端:vue-demo,访问类型选择public创建后端应用客户端创建新客户端:spring-boot-demo,AccessType选择bearer-only保存后,会出现CredentialsTab,在这里记录secret,后面会用到上面创建的两个client的accesstypes。public,bearer-only,那为什么分别选择这种类型,不同的接入类型有什么区别呢?事实上,Keycloak目前有三种访问权限:机密:适用于需要浏览器登录并通过密钥访问token的服务端应用。典型的使用场景是服务端渲染的web系统。public:适用于需要浏览器登录的客户端应用。典型的使用场景是前端web系统,包括用vue和react实现的前端项目。bearer-only:适用于不需要浏览器登录,只允许bearertoken请求的服务端应用。典型的使用场景是restfulapi。创建用户和角色创建角色创建2个角色:ROLE_ADMIN、ROLE_CUSTOMER创建用户创建2个用户:admin、customer绑定用户和角色给admin用户分配角色ROLE_ADMIN给customer用户分配角色ROLE_CUSTOMERVue应用集成Keycloak简明指南创建vue项目vue创建vue-demo添加官方Keycloakjs适配器npmikeycloak-js--savenpmiaxios--savemain.jsimportVuefrom'vue'importAppfrom'./App.vue'importKeycloakfrom'keycloak-js'Vue.config.productionTip=false//keycloakinitoptionsconstinitOptions={url:'http://127.0.0.1:8080/auth',realm:'demo',clientId:'vue-demo',onLoad:'login-required'}constkeycloak=Keycloak(initOptions)keycloak.init({onLoad:initOptions.onLoad,promiseType:'native'}).then((authenticated)=>{if(!authenticated){window.location.reload();}else{Vue.prototype.$keycloak=keycloakconsole.log('Authenticated')}newVue({render:h=>h(App),}).$mount('#app')setInterval(()=>{keycloak.updateToken(70).then((刷新)=>{if(刷新){console.log('令牌刷新');}else{console.log('令牌未刷新,有效期为'+Math.round(keycloak.tokenParsed.exp+keycloak.timeSkew-newDate().getTime()/1000)+'秒');}}).catch(error=>{console.log('Failedtorefreshtoken',error)})},60000)}).catch(error=>{console.log('AuthenticatedFailed',error)})HelloWorld.vue 当前用户:{{user}} 角??色:{{roles}} {{adminMsg}} {{customerMsg}}{{msg}}