Spring Security OAuth 2 教程 - 5:隐式模式 & 资源所有者密码模式

在 “Spring Security OAuth 2 教程 - 4:PKCE 授权码模式” 中,我们学习了如何通过 PKCE 授权码模式获取访问令牌(access_token)。在本文中,我们将了解如何使用隐式模式(Implicit Flow)和资源所有者密码凭证模式(Resource Owner Password Credentials Flow)。

注意

隐式模式和资源所有者密码凭证模式已被淘汰,没有特别理由不应该再使用。

隐式模式

隐式模式(Implicit Flow)是授权码模式(Authorization Code Flow)的一种简化版本,你可以直接通过授权端点(authorization_endpoint)获取访问令牌(access_token)。

如果你一直关注本系列,就会知道如何创建一个启用了特定 “Authentication flow” 的客户端。这里,我们直接为 messages-webapp 客户端启用隐式模式。

要了解如何创建新客户端,请参阅 创建客户端

在浏览器窗口中打开以下 URL:

http://localhost:9191/realms/sivalabs/protocol/openid-connect/auth?
  response_type=id_token%20token
  &client_id=messages-webapp
  &redirect_uri=http://localhost:8080/callback
  &scope=openid%20profile
  &state=randomstring
  &nonce=another_randomstring
  • 然后,你将被重定向到 Keycloak 的登录页面。
  • 使用凭证 siva/siva1234 登录。
  • 然后,你将被重定向到包含 access_tokenid_token 查询参数的重定向 URI。
http://localhost:8080/callback#
  state=randomstring
  &session_state=51692fdb-8b72-45b7-a341-fa73e97b5139
  &id_token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMeVVPTDg4LVBGM3BYQzFpN3BIeGdFZTJwaWZJY3RyTXJiNklHOElmRTlVIn0.eyJleHAiOjE2OTU2MTUzOTQsImlhdCI6MTY5NTYxNDQ5NCwiYXV0aF90aW1lIjoxNjk1NjE0NDk0LCJqdGkiOiI2MjFmNTJmMC0wMDBmLTQ1ZmUtYWYzOC1iY2YzZWM2ZDk1MTEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjkxOTEvcmVhbG1zL3NpdmFsYWJzIiwiYXVkIjoibWVzc2FnZXMtd2ViYXBwIiwic3ViIjoiY2ExYTJmMzQtMTYxNC00NWRkLTg2YzEtNWVhZmZmMDg1ZDhhIiwidHlwIjoiSUQiLCJhenAiOiJtZXNzYWdlcy13ZWJhcHAiLCJub25jZSI6ImFub3RoZXJfcmFuZG9tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjUxNjkyZmRiLThiNzItNDViNy1hMzQxLWZhNzNlOTdiNTEzOSIsImF0X2hhc2giOiJiamR6MC1NeWltQ0xrSzdqaWRRbHp3IiwiYWNyIjoiMSIsInNfaGFzaCI6IlJtVE5Ld0lYaTNXRFhzRFlObTQtUHciLCJzaWQiOiI1MTY5MmZkYi04YjcyLTQ1YjctYTM0MS1mYTczZTk3YjUxMzkiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IlNpdmEgS2F0YW1yZWRkeSIsInByZWZlcnJlZF91c2VybmFtZSI6InNpdmEiLCJnaXZlbl9uYW1lIjoiU2l2YSIsImZhbWlseV9uYW1lIjoiS2F0YW1yZWRkeSIsImVtYWlsIjoic2l2YUBnbWFpbC5jb20ifQ.TIcmVBti96HuZvrYe_14mVJlfopXI2PhdMdWBtPPASpJc-DKrL9argy08sYZKqJTTcmWwnIwKK2o1vddVxA4zUP2tnqqg6ymz1trN3J8r4h-WSvIp907vnS0R7iHei56L6MQX2DZLJ8pOdSmti8wg_9fu4gQJBE2sHRTlrlOP39dh8yohMGidM-Z5iFbLCIzOQXA6B6ewMZll5iwL3ssJ716Ve9cO4qHGCneRGpb3mO7jclY87YSGM-wqr6ur00ylQ_BCGyCdl-f-xskSeDX09iQKFSTX_acMxB7FNi21BL7dMx8_22XPFOwNkX8ha8Vb7eTRMYEMyB776i33FLu0A
  &access_token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMeVVPTDg4LVBGM3BYQzFpN3BIeGdFZTJwaWZJY3RyTXJiNklHOElmRTlVIn0.eyJleHAiOjE2OTU2MTUzOTQsImlhdCI6MTY5NTYxNDQ5NCwiYXV0aF90aW1lIjoxNjk1NjE0NDk0LCJqdGkiOiI1N2NiYmRkMC0wNGFmLTRlMDctYWZlNC02ZmQ5MmY0YjA2MzAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjkxOTEvcmVhbG1zL3NpdmFsYWJzIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImNhMWEyZjM0LTE2MTQtNDVkZC04NmMxLTVlYWZmZjA4NWQ4YSIsInR5cCI6IkJlYXJlciIsImF6cCI6Im1lc3NhZ2VzLXdlYmFwcCIsIm5vbmNlIjoiYW5vdGhlcl9yYW5kb21zdHJpbmciLCJzZXNzaW9uX3N0YXRlIjoiNTE2OTJmZGItOGI3Mi00NWI3LWEzNDEtZmE3M2U5N2I1MTM5IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwOi8vbG9jYWxob3N0OjgwODAiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtc2l2YWxhYnMiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsInNpZCI6IjUxNjkyZmRiLThiNzItNDViNy1hMzQxLWZhNzNlOTdiNTEzOSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiU2l2YSBLYXRhbXJlZGR5IiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2l2YSIsImdpdmVuX25hbWUiOiJTaXZhIiwiZmFtaWx5X25hbWUiOiJLYXRhbXJlZGR5IiwiZW1haWwiOiJzaXZhQGdtYWlsLmNvbSJ9.XsYc69HnM9VaJZFF568nRiZhh8RYEw6Hq2WGnJ4jr3tmZvgMF0QK2RtlBT9BuX4A11XHjyNZqGYNf55x0k4bPXjhPzWI-lC0shhsKrXGYrnhVcComXxMbO_38ypRY_EMeBWRTXu0bvcKInYMjVoItfoLheH-kbcziK6O16yFGftOG-YYw0uVzs_DrOkjQjs1BS2L56yXcRgN72EBXMT-Cv6OLMTSj6WXjfg1nmRl0NRJdeZv0iafSolmqSpJeqXwPzM2hgZ2hPzaq90qipndQrZ05xesMtzXMNlev0ozYPN7xKSa7arHMYky8y4OMpCQDJzkSwekjUEQUSU9Sqg_VA
  &token_type=Bearer
  &expires_in=900

如你所见,access_tokenid_token 是通过浏览器 URL 前端返回的,这并不安全。

资源所有者密码凭证模式

在 “资源所有者密码凭证模式” 中,我们将使用资源所有者(终端用户)凭证获取 access_tokenid_token

直接为 messages-webapp 客户端启用 “Direct access grants”(直接访问授权),即启用 “Resource Owner Password Credentials Grant”。

现在,我们可以通过以下 cURL 命令,通过 token_endpoint 获取 access_tokenid_token

curl --location 'http://localhost:9191/realms/sivalabs/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=messages-webapp' \
--data-urlencode 'username=siva' \
--data-urlencode 'password=siva1234' \
--data-urlencode 'client_secret=qVcg0foCUNyYbgF0Sg52zeIhLYyOwXpQ' \
--data-urlencode 'scope=openid'

这将返回类似下面的 JSON 响应:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMeVVPTDg4LVBGM3BYQzFpN3BIeGdFZTJwaWZJY3RyTXJiNklHOElmRTlVIn0.eyJleHAiOjE2OTU2MTU4NTYsImlhdCI6MTY5NTYxNTU1NiwianRpIjoiZmE4ZDRjZGUtMTk3NS00Mzc1LWJhMTAtMWVjYmJmZjIzZGFlIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo5MTkxL3JlYWxtcy9zaXZhbGFicyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiJjYTFhMmYzNC0xNjE0LTQ1ZGQtODZjMS01ZWFmZmYwODVkOGEiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJtZXNzYWdlcy13ZWJhcHAiLCJzZXNzaW9uX3N0YXRlIjoiYjJiM2YzYTAtYTQwMi00MTdjLWJjOTQtMmMxNzcwZjY0YzE0IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwOi8vbG9jYWxob3N0OjgwODAiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtc2l2YWxhYnMiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsInNpZCI6ImIyYjNmM2EwLWE0MDItNDE3Yy1iYzk0LTJjMTc3MGY2NGMxNCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiU2l2YSBLYXRhbXJlZGR5IiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2l2YSIsImdpdmVuX25hbWUiOiJTaXZhIiwiZmFtaWx5X25hbWUiOiJLYXRhbXJlZGR5IiwiZW1haWwiOiJzaXZhQGdtYWlsLmNvbSJ9.J4UfeHwDT906wPa58pr9a_AIM8UqrBVB8mO1Dvt_FXNLO5DUHUPWv9X25htrHIkl6L4M_SeElOep8MfFBQWeLq-yjrkd7PsXZFh1bjqSscu0bdeIqMOgBdDKZz97XY6UYS5sWjzaws4KvYcbWvLp3athhMts0Jx1Tag57FPWF1SBXwe9ROLQIDmWbm7-jCqiU9GLmBYv9S03SqvXubAXbINDX63-8i7Uyj1NdrXSGARpELdaoc9WZiX28D1eclaPzyI4r3gJ7wxmpRQ-sBTLcC5fanm__Yfuwja0UgjhK6jtCUS_SuxL2uJv4fu3BiQYGyLGHPKmJ9e1ev9PWFU7CQ",
  "expires_in": 300,
  "refresh_expires_in": 1800,
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI5N2E1NTU3Ni01MThlLTQ1MDItOWQyNi1jNzVmYjZhNGRhZWEifQ.eyJleHAiOjE2OTU2MTczNTYsImlhdCI6MTY5NTYxNTU1NiwianRpIjoiOTI0YmVhM2MtYWRmZC00NDUwLWFjZWYtM2U5M2Q3MDI3NzQxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo5MTkxL3JlYWxtcy9zaXZhbGFicyIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6OTE5MS9yZWFsbXMvc2l2YWxhYnMiLCJzdWIiOiJjYTFhMmYzNC0xNjE0LTQ1ZGQtODZjMS01ZWFmZmYwODVkOGEiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoibWVzc2FnZXMtd2ViYXBwIiwic2Vzc2lvbl9zdGF0ZSI6ImIyYjNmM2EwLWE0MDItNDE3Yy1iYzk0LTJjMTc3MGY2NGMxNCIsInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJzaWQiOiJiMmIzZjNhMC1hNDAyLTQxN2MtYmM5NC0yYzE3NzBmNjRjMTQifQ._1_ODyFLuiOt6kquAQM9MAJpVCBlD6XphSsdaI0d9YM",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMeVVPTDg4LVBGM3BYQzFpN3BIeGdFZTJwaWZJY3RyTXJiNklHOElmRTlVIn0.eyJleHAiOjE2OTU2MTU4NTYsImlhdCI6MTY5NTYxNTU1NiwiYXV0aF90aW1lIjowLCJqdGkiOiJkMWRiMzZkMC1kYmMyLTRmYmUtODE4ZS1mMmNjMWUwNzU5NjMiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjkxOTEvcmVhbG1zL3NpdmFsYWJzIiwiYXVkIjoibWVzc2FnZXMtd2ViYXBwIiwic3ViIjoiY2ExYTJmMzQtMTYxNC00NWRkLTg2YzEtNWVhZmZmMDg1ZDhhIiwidHlwIjoiSUQiLCJhenAiOiJtZXNzYWdlcy13ZWJhcHAiLCJzZXNzaW9uX3N0YXRlIjoiYjJiM2YzYTAtYTQwMi00MTdjLWJjOTQtMmMxNzcwZjY0YzE0IiwiYXRfaGFzaCI6IjZ4Rk1lTjR6a1Q1UkIzdE9lWFRteEEiLCJhY3IiOiIxIiwic2lkIjoiYjJiM2YzYTAtYTQwMi00MTdjLWJjOTQtMmMxNzcwZjY0YzE0IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJTaXZhIEthdGFtcmVkZHkiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzaXZhIiwiZ2l2ZW5fbmFtZSI6IlNpdmEiLCJmYW1pbHlfbmFtZSI6IkthdGFtcmVkZHkiLCJlbWFpbCI6InNpdmFAZ21haWwuY29tIn0.UPR78Ps7colWhBAHcGr6hvx4bQdEnvt6j9oDuFtRLTYRMCSb-dlG73ehWDov7AEczcPtfnoEamBgJ_5Hr9XQvA0oQ_9ye8JT6bPrUuUxB-CK6BPsdtyHNyV6jnxolkz26QYsfsB-fHBObnlwVZEKouiGwdGl08GR8xPlqZgK-f1Lo6kKnqLE4i6hdEzJP_z1N5-TE2pSQ-eqc792Mg5z2WB04ug5m2B_NSODVSnXZ_KzYwI7aEKgHBnDac9uisDJrSfqxr2V4lysyRMjUN4odK10hFBn0MdsI-Z1a7d3DKjssyBGZ9k0ZXNWfOBAtzZH7W5s7fLcOViPLYBxgTNUkw",
  "not-before-policy": 0,
  "session_state": "b2b3f3a0-a402-417c-bc94-2c1770f64c14",
  "scope": "openid email profile"
}

如你所见,使用 “资源所有者密码凭证模式” 时,终端用户需要与客户端应用共享其凭证,这并不可取。

总结

在本文中,我们学习了如何通过隐式模式(Implicit Flow)和资源所有者密码凭证模式(Resource Owner Password Credentials Flow)获取 access_token记住,“隐式模式” 和 “资源所有者密码凭证模式” 已被删除,不建议再使用

到目前为止,我们已经学会了如何使用各种 OAuth 2 和 OpenID Connect Flow。接下来,我们将开始构建 Spring Boot 应用程序,并使用 Spring Security OAuth 2 和 Keycloak 进行认证和访问控制。


参考:https://www.sivalabs.in/spring-security-oauth2-tutorial-implicit-and-resource-owner-password-credentials-flow/