前言
1. scope
引數的作用
- 定義許可權:
scope
用於宣告請求訪問的資源和許可權。常見的值包括openid
、profile
、email
等。 - 影響返回的資料:如果你在授權請求中指定了某些
scope
,在後續的 token 請求中,Keycloak 會根據這些scope
返回相應的資訊。
- openid用於指示請求者希望使用 OpenID Connect 進行身份驗證
- 獲取 ID Token:當你在授權請求中包含 openid 時,Keycloak 會返回一個 ID Token,包含使用者的身份資訊,反之,scope裡不加openid,則不會生成ID Token這個欄位。
2. 在不同階段使用 scope
-
授權請求階段 (
/protocol/openid-connect/auth
):- 可以傳遞
scope
引數,以便在使用者同意授權時,明確所請求的許可權。
- 可以傳遞
-
令牌請求階段 (
/protocol/openid-connect/token
):- 也可以在此階段傳遞
scope
,但通常情況下,如果在授權請求中已指定scope
,則不需要在此再次指定; - 在授權中指定了
scope
,這裡再指定是無效的,以授權中指定的值
為準
- 也可以在此階段傳遞
3. 示例
以下是一個獲取授權碼的請求示例:
GET /auth/realms/{realm}/protocol/openid-connect/auth?
response_type=code&
client_id={client_id}&
redirect_uri={redirect_uri}&
scope=openid profile
4. 總結
- 建議:雖然
scope
在授權請求中是可選的,但為了確保獲得正確的許可權和資料,建議在請求中包含scope
引數。 - 注意:在實際開發中,根據你的應用需求合理配置
scope
是非常重要的。
實踐
oauth2授權碼認證的過程
1. 配置客戶端及scope模板
- 預設模板,無論應用是否傳scope,預設模板裡的許可權都會被啟用
- 可選模板,由使用者自己選擇,透過scope來體現,它會追加到預設模板後面
2. 獲取授權碼
- scope中體現了獲取使用者的email,這一步是由使用者自己選擇的公開的資訊
- 地址:/auth/realms/{realm}/protocol/openid-connect/auth?client_id=dahengshuju&scope=profile email&redirect_uri=http://www.baidu.com&response_type=code
3. 表單認證
- 提示使用者輸入賬號密碼進行登入
- 登入成功後,重定向到來源頁,帶上code碼
- code授權碼使用一次後,立即過期
4. 獲取token
- 透過步驟3,獲取到的code,它透過scope來限制授權的範圍【即token和獲取使用者資訊中包含的欄位集合】
- 步驟2指定了scope,這一步再指定scope是無效的,二選一即可
- 地址:/auth/realms/{realm}/protocol/openid-connect/token
- 請求表型別:x-www-form-urlencoded
- 請求引數
grant_type:authorization_code
code:3be438fe-8651-4a84-8141-976b76e671e1.75cab95f-a1ec-4b9b-9a6e-8f1ecb651cd6.61d819de-33e4-4006-ae66-dd7609ea2d3e
client_id:dahengshuju
client_secret:9e3de70f-d5cd-4d11-a8aa-85fd3af13265
scope:profile
- 這是scope為profile email的token
{
"exp": 1727233162,
"iat": 1727231362,
"auth_time": 1727229121,
"jti": "bb296d9d-d521-45b1-aab9-8cb6bea0ddc3",
"iss": "https://xx.xx.com/auth/realms/xx",
"sub": "347c9e9e-076c-45e3-be74-c482fffcc6e5",
"typ": "Bearer",
"azp": "dahengshuju",
"session_state": "75cab95f-a1ec-4b9b-9a6e-8f1ecb651cd6",
"acr": "0",
"scope": "email profile",
"email_verified": false,
"preferred_username": "test",
"locale": "zh-CN",
"email": "bfyxzls@gmail.com"
}
- 這是scope為profile的token,裡面是沒有email資訊的
{
"exp": 1727233521,
"iat": 1727231721,
"auth_time": 1727229121,
"jti": "f7de8ad9-7558-4f4a-8761-8724f685febb",
"iss": "https://xx.xx.com/auth/realms/xx",
"sub": "347c9e9e-076c-45e3-be74-c482fffcc6e5",
"typ": "Bearer",
"azp": "dahengshuju",
"session_state": "75cab95f-a1ec-4b9b-9a6e-8f1ecb651cd6",
"acr": "0",
"scope": "profile",
"preferred_username": "test",
"locale": "zh-CN"
}
5. 透過access_token獲取使用者資訊
- 使用者資訊主要是對token中的內容進行解析
- 地址:/auth/realms/{realm}/protocol/openid-connect/userinfo
- 請求頭:Authorization: Bearer
{
"sub": "347c9e9e-076c-45e3-be74-c482fffcc6e5",
"email_verified": false,
"preferred_username": "test",
"locale": "zh-CN",
"email": "xxx@gmail.com"
}