keycloak介绍和sso对接

keycloak简介:

这里使用的keycloak作为单点登入服务器的应用,但是keycloak不仅于sso的功能

通过Keycloak处理用户认证,用户不需要再次登录Keycloak管理下的其它应用。实现一次登录,多处登录不同应用,一处登出,所有应用登出。

keycloak核心概念:

users:用户是一个可以登陆系统的实体,它可以拥有联系它们自身的属性,例如邮箱、用户名、地址、电话号码或生日等,可以为user分配组别或者角色。

authentication:相当于密码,可以验证和识别一个user。

authorization:给予用户访问的过程。

credentials:证书,可以供keycloak验证用户的东西,例如密码、一次性密码、证书、指纹等。

roles:相当于用户的一个分类 ,一个组织可能有Admin\user\manager\emplee等角色,应用程序经常会分配权限给角色,而不是用户,因为用户太难管理。

user role mapping:定义了一个用户及角色的关系,一个用户可以属于零个或多个角色,用户与角色的映射关系,这样就可以决定用在各种资源访问的权限管理。

composite roles:复合角色可以包含其他的角色,用户拥有了复合角色就相当于拥有了它下面的所有子角色。

groups:组可以一组的用户,也可以将角色映射到角色中,用户可以成为组员后继承用组的角色

realms:领域,领域管理着一批,用户、证书、角色、组等,一个用户只能属于且能登陆到一个域,域之间是互相独立的,域只能管理在它下面的用户。

clients:客户端是一个实体,可以请求keycloak对用户进行身份验证,大部分情况下,客户端是应用或服务希望使用keycloak来保护自己和提供一个单点登录的解决方案。客户端也可以是一个实体,请求身份信息或一个访问信息,这样就可以调用其他keycloak保护的应用或服务了。

单点登入协议protocols:

对比点 OAuth2| OpenID| SMAL

票据格式 JSON or SAML2| JSON| XML

支持授权 Yes| No| Yes

支持认证 “伪认证” |Yes| Yes

创建年份 2005| 2006| 2001

最新版本 OAuth2| OpenID Connect| SAML 2.0

传输方式 HTTP| HTTP GET and HTTP POST | HTTP重定向,SAML SOAP绑定,HTTP POST绑定等

安全弱点 不能抵抗网络钓鱼,OAuth没有使用数据签名和加密等措施,数据安全完全依赖TLS |不能抵抗网络钓鱼,一个钓鱼的IDP如果恶意记录下来用户的OpenID,将会造成很严重的隐私安全问题| XML签名存在漏洞,可能被伪造

使用场景 API 授权 商用应用的单点登录 企业级单点登录,但是对于移动端支持不是很好

  • openid connect

是openid的三代产品,是基于oauth协议,openid1和2只有认证(authenticate)功能,openid connect有了授权(authorize)功能

jwt简介

jwt有以下特性:

  • 自包含性:jwt本身解析出来就包换大量的信息,用户的信息,权限信息等

  • 紧凑性

  • 防篡改:jwt一般base64加密,为了信息不被篡改,有数字请签名等校验方式

jwt是数据形式,这里对jwt进行扩展,包含jws和jwe,jws相当于有数字签名,jwe更加复杂,计算繁琐,信息都是加密的,适合数据传输,不适合token认证。

客户端授权模式

implicit:简化模式,(不安全,适用于纯静态页面应用)

authorization code:授权码模式(功能最完整、流程最严密的授权模式,通常使用在公网的开放平台中)

resource owner password credentials:密码模式(一般在内部系统中使用,调用者是以用户为单位,用在系统间高度信任的场景,因为有密码泄露的风险。)

client credentials:客户端模式(一般在内部系统之间的API调用。两个平台之间调用。比如调用消息服务、日志模块等,调用者是以平台为单位。)

vue对接keycloak

keycloak官网有js的对接方案,这里使用了vue的解决方案,参考:https://github.com/dsb-norge/vue-keycloak-js

引入执行:

npm i --save @dsb-norge/vue-keycloak-js 

关键代码分析:

Vue.use(keycloak , {
    init: {
        onLoad: 'login-required'
    },
    config: {  // 这里配置keycloak的服务地址,和client信息
        url: 'http://192.168.1.186:8080/auth',
        realm: 'test',
        clientId: 'pandora'
    },
    onReady: (keycloak) => {
        // keycloak.token 是keycloak生成的token信息 jwt格式
        console.log("token:"+keycloak.token)
        keycloak.loadUserProfile().success((data) => {
            // 通过token检验用户信息,返回登入用户的username
            console.log("user:"+data.username);
            this.username = data.username;
            // 通过username获取pandora的token
            // generateToken(this.username);
        });
    }
});

注意事项:使用的时候使用的history的路由配置,使用hash会导致重定向问题,dsb-norge开源项目示例也是使用的history配置。

springboot对接keycloak

在pom.xml文件中插入

<!-- keycloak相关-->
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-spring-boot-starter</artifactId>
        <version>10.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.keycloak.bom</groupId>
        <artifactId>keycloak-adapter-bom</artifactId>
        <version>10.0.1</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>

在application.yml中配置keycloak服务器和权限相关的

keycloak:
    realm: test
    auth-server-url: http://192.168.1.186:8080/auth
    ssl-required: external
    resource: springboot
    credentials:
        secret:
    use-resource-role-mappings: true
    security-constraints[0]:
        authRoles[0]: admin
        authRoles[1]: user
        securityCollections[0]:
            name: insecure stuff
            patterns[0]: /*

pandora请求接口

简要描述:

通过username换取平台token信息

请求URL:

  • /sso/username_login

请求方式:

  • get

参数:

  • 参数名:username

  • 类型:String

  • 示例:admin

返回示例

1
2
3
4
5
6
{
"msg": "success",
"code": 0,
"expire": 43200,
"token": "69e97d3500f06d594c1d0ba8950f2a76"
}