主要内容
- 密码认证
- 授权码认证
哪个client申请的code,使用哪个client获取token
- 客户端认证
在kc开通了服务端帐号之后,可通过client_id和client_secret来获取token,与用户无关,无刷新token机制
- 自动触发社区认证
当用户在社区网站上登录后,访问这个地址可自动登录法宝
- 验证token是否在线
可使用任意client来验证所有token的在线性
- refresh_token刷新token
哪个client生成的token,就用哪个client去刷新
- 登出/注销
官方post方式和浏览器302方式
密码认证
-
POST /auth/realms/your-realm/protocol/openid-connect/token
-
请求体 x-www-form-urlencoded
grant_type:password
username:test
password:123456
client_secret:ec0fd1c6-68b0-4c39-a9fa-c3be25c8ef01
client_id:democlient -
响应
{
"access_token": "..",
"expires_in": 3000,
"refresh_expires_in": 1800,
"refresh_token": "..",
"token_type": "bearer",
"not-before-policy": 1619512543,
"session_state": "765969ec-94da-4edb-9dcb-e15ea3e0ad3b",
"scope": "roles email profile"
}
授权码认证
注意的几点
-
code时的redirect_uri和authorization_code的需要是一致的,不一致的错误
{
"error": "invalid_grant",
"error_description": "redirect_uri error"
} -
code时的client_id和client_secret和authorization_code的需要是一致的,不一致的错误,
这块我已经修改了源码,去掉了这个限制
{
"error": "invalid_grant",
"error_description": "Auth error"
} -
code的组成
它由3部分组成,中间使用.分割,第一部分是UUID,第二部分是用户会话ID【session_state】,第三部分是客户端ID,例如:5c33f9a2-cbf4-4804-a8ee-e2d076eda2d6.40be5301-f41b-4f0d-97e7-d2074db2801c.ff591897-7654-460e-9c19-8e8f92117768
请求code
-
GET /auth/realms/your-realm/protocol/openid-connect/auth
-
QUERY
client_id:democlient
scope:openid
response_type:code
client_secret:ec0fd1c6-68b0-4c39-a9fa-c3be25c8ef01
redirect_uri:http://localhost:9090/callback -
跳转到kc的登录页,完成用户名和密码的登录

- 登录成功之后,跳回callback删除,在url参数上带上了code

请求token
-
POST /auth/realms/your-realm/protocol/openid-connect/token
-
请求体 x-www-form-urlencoded
grant_type:authorization_code
code:68058719-add6-4b40-ab96-8e71af03827a.7a31b1a9-c3e8-46d4-b8cc-345012fcf4a2.25e52f60-5991-43dd-9108-873f60af385d
client_id:democlient
client_secret:ec0fd1c6-68b0-4c39-a9fa-c3be25c8ef01
scope:openid
redirect_uri:http://localhost:9090/callback -
响应
{
"access_token": "..",
"expires_in": 3000,
"refresh_expires_in": 1800,
"refresh_token": "..",
"token_type": "bearer",
"id_token": "..*",
"not-before-policy": 1619660302,
"session_state": "14812f50-b9f7-4cee-be56-bf9bef5c961a",
"scope": "openid roles email profile"
}
客户端认证
客户端认证,与用户无关,主要保证向keycloak发起的请求,来自合法的client即可(由keycloak颁发的client)
-
POST /auth/realms/your-realm/protocol/openid-connect/token
-
请求
x-www-form-urlencoded
-
参数
grant_type:client_credentials
client_secret:912ecc47-60b1-4dd4-8f62-c7745c293cab
client_id:kce -
注意,需要在keycloak客户端配置开启
服务账号

-
如果没有开启
服务账号
,将出现下面异常{
"error": "unauthorized_client",
"error_description": "Client not enabled to retrieve service account"
}
自动触发社区认证
carsi中出现的东西,院校希望直接通过固定的uri实现社区登录,故开发这个功能
- 地址:GET https://kc.democlient.com/auth/realms/your-realm/protocol/openid-connect/auth?scope=openid&response_type=code&client_id=carsi-auto&redirect_uri=https://www.baidu.com
- 首先,需要在配置
Authentication Flows
中的brower中的社区登录的有限级最高,我们可以复制一个brower认证流,在新流上修改,用户密码认证步骤关闭,也可以删除

- 这个里的重定向认证使用的认证流是carsi

- 其次,需要新添加客户端,专门用来发送社区自动认证请求的,如
carsi-auto
,或者配置客户端的自定义认证方式

- 最后,测试一下,你可以看到,通过这个地址,可以唤起社区登录,最后回调到我们OIDC认证上来

验证token是否在线
是否触发了keycloak的logout接口,如果触发了,那token将被删除,在线状态active为false,如果不希望提供client_secret参数,也可以通过
/auth/realms/your-realm/protocol/openid-connect/userinfo
接口来判断token是否有效,httpcode为401表示token失效.
-
使用场景:a客户端在kc申请的token,可以在b客户端调用kc的接口去校验它的合法性
-
POST /auth/realms/your-realm/protocol/openid-connect/token/introspect
-
请求体 x-www-form-urlencoded
token:..*
client_id:democlient
client_secret:ec0fd1c6-68b0-4c39-a9fa-c3be25c8ef01 -
响应,状态码都是200,如果json体中active为false,表示已经离线
{
"active": false
}
refresh_token刷新token
注意,刷新token与客户端有关,自己客户端生产的access_token,只能由自己客户端去refresh_token刷新
-
POST /auth/realms/your-realm/protocol/openid-connect/token
grant_type:refresh_token
refresh_token:..*
client_id:democlient
client_secret:ec0fd1c6-68b0-4c39-a9fa-c3be25c8ef01 -
响应
新的token对象{
"access_token": "..",
"expires_in": 3000,
"refresh_expires_in": 1800,
"refresh_token": "..",
"token_type": "bearer",
"not-before-policy": 1621497420,
"session_state": "405d25b0-5128-45ae-9934-953eecb79894",
"scope": "roles profile"
}
登出/注销
KC的登出是属于会话的登出,通过这个会话产生的所有token(一个会话可能对应多个不同client的token)都将会退出
一般地,如果是前后不分享项目,应该还会清除自己网站的session会话,然后再去调用KC的接口
-
POST /auth/realms/your-realm/protocol/openid-connect/logout
-
请求体 x-www-form-urlencoded
refresh_token:..*
client_id:democlient
client_secret:ec0fd1c6-68b0-4c39-a9fa-c3be25c8ef01 -
响应
HttpCode为200或者204表示操作成功
-
浏览器端可通过这个接口来实现
302浏览器跳转
方式的登出GET /auth/realms/your-realm/sms/remove-sessions?redirect_uri={redirect_uri}
登出后,KC会跳转到redirectUri的页面