keycloak~账号密码认证和授权码认证

重要的事说在前头

  • /protocol/openid-connect/token请求过程中(认证,获取code,刷新token等), client_id要保持一致,不能混用
  • 使用哪个client_id进行的表单登录,生成的code码,就用哪个client_id来获取token
  • token中是哪个client_id,就用哪个client_id来刷新token

概念

OAuth 2.0 中的授权码认证(Authorization Code Grant)是一种常用的身份验证和授权方式,主要用于用户通过第三方应用访问受保护的资源。以下是关于授权码认证的详细介绍:

授权码认证流程

  1. 用户请求授权

    • 用户在客户端应用(如移动应用或网页)上点击“登录”或“授权”按钮。
    • 客户端将用户重定向到授权服务器的授权端点,并附带一些参数,包括:
      • response_type=code:表示请求授权码。
      • client_id:客户端的唯一标识符。
      • redirect_uri:用户授权后重定向的地址。
      • scope:请求的权限范围。
      • state:防止CSRF攻击的随机字符串。
  2. 用户登录并授予权限

    • 用户在授权服务器上登录(如果尚未登录),并查看客户端请求的权限范围。
    • 用户同意授权后,授权服务器会生成一个授权码,并将其附加到重定向URI中返回给客户端。
  3. 客户端使用授权码获取访问令牌

    • 客户端接收到授权码后,会向授权服务器的令牌端点发送请求,包含以下信息:
      • grant_type=authorization_code:表示使用授权码模式。
      • code:刚才获得的授权码。
      • redirect_uri:与初始请求中的重定向URI相同。
      • client_idclient_secret:用于验证客户端身份。
  4. 授权服务器返回访问令牌

    • 授权服务器验证授权码和其他信息是否有效。如果有效,将生成并返回访问令牌(Access Token)和可选的刷新令牌(Refresh Token)。
  5. 客户端使用访问令牌访问资源

    • 客户端可以使用获取到的访问令牌来访问受保护的资源,通常是在请求头中添加 Authorization: Bearer {access_token}

优势

  • 安全性高:由于访问令牌是通过授权码交换得到的,避免了在用户的浏览器中直接暴露访问令牌。
  • 适用于用户代理:特别适合需要用户交互的场景,如Web应用和移动应用。
  • 支持单点登录:用户只需登录一次,即可在多个客户端之间共享访问令牌。

注意事项

  • 使用 HTTPS 来保护通信,防止中间人攻击。
  • state 参数用于防止 CSRF 攻击,确保请求的完整性。
  • 授权码通常是短期有效的,访问令牌也可能有过期时间,需合理管理。

示例图解

用户 --> 客户端 --> 授权服务器
    |             |
    |-- 登录 ---->|
    |<--- 授权码-|
    |             |
    |-- 访问令牌->|
    |<--- 资源 ---|

keycloak中授权码认证的过程

一 密码认证[direct grant]

  • POST /auth/realms/demo/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": "xxx",
    "expires_in": 3000,
    "refresh_expires_in": 1800,
    "refresh_token": "xxx",
    "token_type": "bearer",
    "not-before-policy": 1619512543,
    "session_state": "765969ec-94da-4edb-9dcb-e15ea3e0ad3b",
    "scope": "roles email profile"
}

二 授权码登录

请求code

对于没有认证的接口,将会返回401,即没有登录,这时keycloak会将我们的请求重定向到keycloak的登录而,这时有几个参数将被发到keycloak服务端,用来获取code信息。
主要包括以下几个参数 :

Response_type:表示响应类型,这里我们是code
Client_id:表示为你这个客户端颁发的唯一标识
Redirect_uri:表示从keycloak服务端注册的合法的回调地址,支持通配符
Scope:表示认证范围,表示用户的openid方式
  • GET /auth/realms/demo/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/fabao/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": "xxx",
    "expires_in": 3000,
    "refresh_expires_in": 1800,
    "refresh_token": "xxx",
    "token_type": "bearer",
    "id_token": "xxx",
    "not-before-policy": 1619660302,
    "session_state": "14812f50-b9f7-4cee-be56-bf9bef5c961a",
    "scope": "openid roles email profile"
}

三 JWT token解析

  • PAYLOAD数据载体主要包括用户ID,用户名,用户角色,过期时间等信息
  • Sub:用户ID
  • preferred_username:账号名称
  • Name:用户姓名
  • Email:电子邮件
  • realm_access:领域角色
  • resource_access:客户端(资源服务)角色
  • Azp:授权客户端
  • Typ:token的类型
  • Aud:被授权的客户端列表
  • Exp:过期时间
  • Iss: 当前领域的开放API

四 Scope对jwt的影响

我们可以配置域的scope,或者对指定的client配置 scope,如图

图中,我们把客户端democlient的scope里的roles移除后,在返回的token里将不会出现和角色有关的信息,即realm_access和resource_access将被移除。

posted @ 2021-04-29 10:12  张占岭  阅读(8636)  评论(3编辑  收藏  举报