本文提供一個Okta與阿里雲進行OIDC角色SSO的樣本,使Okta中的應用通過臨時身份憑證(STS Token)安全訪問阿里雲資源。
前提條件
請提前在Okta中註冊一個OIDC應用,並擷取應用的頒發者URL和用戶端ID(Client ID)。本樣本中使用的資料如下:
頒發者URL:https://dev-xxxxxx.okta.com
用戶端ID:0oa294vi1vJoClev****
步驟一:在阿里雲建立OIDC身份供應商
本步驟中將建立一個名為TestOidcProvider的OIDC身份供應商。頒發者URL為https://dev-xxxxxx.okta.com,用戶端ID為0oa294vi1vJoClev****。
使用Resource Access Management員登入RAM控制台。
在左側導覽列,選擇。
在角色SSO頁簽,先單擊OIDC頁簽,然後單擊建立身份供應商。
在建立身份供應商頁面,設定身份供應商資訊。
參數
說明
身份供應商名稱
同一個阿里雲帳號下必須唯一。
頒發者URL
頒發者URL由外部IdP提供。頒發者URL必須以
https開頭,符合標準URL格式,但不允許帶有query參數(以?標識)、fragment片段(以#標識)和登入資訊(以@標識)。驗證指紋
為了防止頒發者URL被惡意劫持或篡改,您需要配置外部IdP的HTTPS CA認證產生的驗證指紋。
填寫完頒發者URL後,您可以單擊擷取指紋,阿里雲會輔助您自動計算出驗證指紋,但是建議您在本地自己計算一次(例如:通過OpenSSL擷取OIDC IdP的指紋),與阿里雲計算的指紋進行對比。如果對比發現不同,則說明該頒發者URL可能已經受到攻擊,請您務必再次確認,並填寫正確的指紋。
說明當您的IdP計划進行認證輪轉時,請在輪轉前產生新認證的指紋並添加到阿里雲OIDC身份供應商資訊中,一段時間(至少一天)以後再進行認證輪轉,認證輪轉確認可以換取到STS Token後再刪除舊的指紋。
用戶端ID
您的應用在外部IdP註冊的時候,會產生一個用戶端ID(Client ID)。當您從外部IdP申請簽發OIDC令牌(OIDC Token)時必須使用該用戶端ID,簽發出來的OIDC Token也會通過
aud欄位攜帶該用戶端ID。在建立OIDC身份供應商時配置該用戶端ID,然後在使用OIDC Token換取STS Token時,阿里雲會校正OIDC Token中aud欄位所攜帶的用戶端ID與OIDC身份供應商中配置的用戶端ID是否一致。只有一致時,才允許扮演角色。如果您有多個應用需要訪問阿里雲,您可以配置多個用戶端ID,但最多不能超過50個。
最早頒發時間限制
在該限制時間之前頒發的OIDC Token不允許換取STS Token。
預設值:12小時。取值範圍:1~168小時。
備忘
身份供應商的描述資訊。
單擊建立身份供應商。
步驟二:在阿里雲建立可信實體為OIDC身份供應商的RAM角色
本步驟中將建立一個名為testoidc的RAM角色,身份供應商選擇步驟一建立的TestOidcProvider。
使用Resource Access Management員登入RAM控制台。
在左側導覽列,選擇。
在角色頁面,單擊建立角色。

在建立角色頁面的右上方,單擊切換編輯器。

在編輯器中指定具體的OIDC身份供應商。
編輯器支援可視化編輯和指令碼編輯兩種模式,您可以任選其一。
可視化編輯
在主體中指定具體的OIDC身份供應商。


指令碼編輯
在
Principal的Federated欄位中指定具體的OIDC供應商,同時配置Condition。{ "Version": "1", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "acs:ram::100*******0719:oidc-provider/xiyun****" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "oidc:iss": [ "https://dev-xxxxxx.okta.com" ], "oidc:aud": [ "0oa294vi1vJoClev****" ] } } } ] }
在編輯器中設定限制條件。
支援的服務級限制條件如下表所示:
限制條件關鍵字
說明
是否必選
樣本
oidc:issOIDC頒發者(Issuer)。用來扮演角色的OIDC令牌中的iss欄位值必須滿足該限制條件要求,角色才允許被扮演。
該限定條件必須使用StringEquals作為條件操作類型,條件值只能是您在OIDC身份供應商中填寫的頒發者URL。該限制條件用於確保只有受信頒發者頒發的OIDC令牌才能扮演角色。
是
https://dev-xxxxxx.okta.com
oidc:audOIDC受眾(Audience)。用來扮演角色的OIDC令牌中的aud欄位值必須滿足該限制條件要求,角色才允許被扮演。
該限定條件必須使用StringEquals作為條件操作類型,您可選擇在OIDC身份供應商中配置的一個或多個用戶端ID(Client ID)作為條件值。該限制條件用於確保只有您設定的Client ID產生的OIDC令牌才能扮演角色。
是
0oa294vi1vJoClev****
oidc:subOIDC主體(Subject)。用來扮演角色的OIDC令牌中的sub欄位值必須滿足該限制條件要求時,角色才允許被扮演。
該限定條件可以使用任何String類的條件操作類型,且您可以最多設定10個OIDC主體作為條件值。該限制條件用於進一步限制允許扮演角色的身份主體,您也可以不指定該限制條件。
否
00u294e3mzNXt4Hi****
在建立角色對話方塊,輸入角色名稱,然後單擊確定。
步驟三:為RAM角色授權
您可以根據實際需要,為步驟二建立的RAM角色testoidc授予訪問阿里雲資源的許可權。
使用Resource Access Management員登入RAM控制台。
在左側導覽列,選擇。
在角色頁面,單擊目標RAM角色操作列的新增授權。

您也可以選中多個RAM角色,單擊角色列表下方的新增授權,為RAM角色大量授權。
在新增授權面板,為RAM角色授權。
選擇資源範圍。
帳號層級:許可權在當前阿里雲帳號內生效。
資源群組層級:許可權在指定的資源群組內生效。
說明指定資源群組授權生效的前提是該雲端服務及資源類型已支援資源群組,詳情請參見支援資源群組的雲端服務。
選擇授權主體。
授權主體即需要添加許可權的RAM角色。系統會自動選擇當前的RAM角色。
選擇權限原則。
權限原則是一組存取權限的集合。支援批量選中多條權限原則。
系統策略:由阿里雲建立,策略的版本更新由阿里雲維護,使用者只能使用不能修改。更多資訊,請參見支援RAM的雲端服務。
說明系統會自動標識出高風險系統策略(例如:AdministratorAccess、AliyunRAMFullAccess等),授權時,盡量避免授予不必要的高風險權限原則。
自訂策略:由使用者管理,策略的版本更新由使用者維護。使用者可以自主建立、更新和刪除自訂策略。更多資訊,請參見建立自訂權限原則。
單擊確認新增授權。
單擊關閉。
步驟四:在Okta簽發OIDC令牌(OIDC Token)
阿里雲不支援使用OIDC登入控制台,所以您需要使用程式訪問的方式完成OIDC SSO流程。由於產生OIDC Token本質上是個OAuth流程,所以您需要通過標準的OAuth 2.0流程從OIDC IdP(例如:Okta)擷取OIDC Token。OAuth支援多種流程,例如:比較常見的Authorization Code Flow。
下文以Okta官方教程使用AuthJS登入單頁應用(SPA)為例,示範如何從Okta擷取OIDC Token。
按照Okta的教程建立應用並完成專案配置。
在瀏覽器中測試專案,應用將自動重新導向到Okta登入頁面。完成登入和MFA認證後,頁面將重新導向至
index.html。頁面會顯示當前登入使用者的ID Token及其解析後的Claims資訊。如下所示:{ "idToken": "eyJraWQiOiItbUF****", "claims": { "sub": "00uxbq0z40UYy9bm****", "name": "ssotest01", "email": "ssotest01@exampledomain.com", "ver": 1, "iss": "https://dev-xxxxxx.okta.com", "aud": "0oaxbqhfrfBl5lk2****", "iat": 1762841679, "exp": 1762845279, "jti": "ID.WYtCLmLKOlMcEh0uIe1jWH9T6M1JmotCvX3hIgLK6mA", "amr": [ "mfa", "otp", "pwd", "okta_verify" ], "idp": "00oxbpgns1TnfLFg****", "nonce": "Xp0PTyQzw9ltYBY7SfhxG2ijt1wgi2jK6XLZOGbeQJQ79d0ScWYoHE5twl0QAklA", "preferred_username": "ssotest01@exampledomain.com", "auth_time": 1762841677, "at_hash": "wztv8ALAo2Au56Om3dya7w" }, "expiresAt": 1762845279, "scopes": [ "openid", "profile", "email" ], "authorizeUrl": "https://dev-xxxxxx.okta.com/oauth2/v1/authorize", "issuer": "https://dev-xxxxxx.okta.com", "clientId": "0oaxbqhfrfBl5lk2****" }說明在頁面展示的claims資訊中,找到以下屬性,並確保它們與在步驟一:在阿里雲建立OIDC身份供應商中配置的OIDC身份供應商資訊匹配,否則在調用AssumeRoleWithOIDC API時將會失敗。
iss:必須與頒發者URL完全符合
aud:必須與用戶端ID完全符合
複製頁面中所展示的
idToken並儲存。
步驟五:使用OIDC Token換取STS Token
您可以直接調用AssumeRoleWithOIDC API,使用從步驟四中擷取的OIDC Token(ID token)換取STS Token。
請求樣本:
package demo;
import com.aliyun.auth.credentials.provider.AnonymousCredentialProvider;
import com.aliyun.sdk.service.sts20150401.models.*;
import com.aliyun.sdk.service.sts20150401.*;
import com.google.gson.Gson;
import darabonba.core.client.ClientOverrideConfiguration;
import java.util.concurrent.CompletableFuture;
public class AssumeRoleWithOIDC {
public static void main(String[] args) throws Exception {
// Anonymous access method (requires API support)
AnonymousCredentialProvider provider = AnonymousCredentialProvider.create();
// Configure the Client
AsyncClient client = AsyncClient.builder()
.region("cn-hangzhou") // Region ID
.credentialsProvider(provider)
// Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
.overrideConfiguration(
ClientOverrideConfiguration.create()
// Endpoint 請參考 https://api.aliyun.com/product/Sts
.setEndpointOverride("sts.cn-hangzhou.aliyuncs.com")
)
.build();
String idToken = "eyJraWQiOiItbUF****"; // OIDC id token
// Parameter settings for API request
AssumeRoleWithOIDCRequest assumeRoleWithOIDCRequest = AssumeRoleWithOIDCRequest.builder()
.OIDCToken(idToken)
.roleArn("acs:ram::173305794806****:role/testoidc")
.OIDCProviderArn("acs:ram::173305794806****:oidc-provider/Okta")
.roleSessionName("test-oidc-session")
.build();
// Asynchronously get the return value of the API request
CompletableFuture<AssumeRoleWithOIDCResponse> response = client.assumeRoleWithOIDC(assumeRoleWithOIDCRequest);
// Synchronously get the return value of the API request
AssumeRoleWithOIDCResponse resp = response.get();
System.out.println("RequestId: " + resp.getBody().getRequestId());
System.out.println("Assume role ARN: " + resp.getBody().getAssumedRoleUser().getArn());
System.out.println("Credentials AccessKeyId: " + resp.getBody().getCredentials().getAccessKeyId());
System.out.println("Credentials AccessKeySecret: " + resp.getBody().getCredentials().getAccessKeySecret());
System.out.println("Success response: " + new Gson().toJson(resp.getBody()));
// Finally, close the client
client.close();
}
}
返回樣本:
RequestId: 5EB6E605-15EA-5D96-941D-2C62DC99****
Assume role ARN: acs:ram::173305794806****:role/testoidc/test-oidc-session
Credentials AccessKeyId: STS.NZXMTBGTTHLW74AMVYKou****
Credentials AccessKeySecret: FdrYjJwTCfFfMdY4APdHsjGL9fH5RSZCtRyYMJED****
Success response:
{
"assumedRoleUser": {
"arn": "acs:ram::173305794806****:role/testoidc/test-oidc-session",
"assumedRoleId": "30048007026011****:test-oidc-session"
},
"credentials": {
"accessKeyId": "STS.NZXMTBGTTHLW74AMVYKou****",
"accessKeySecret": "FdrYjJwTCfFfMdY4APdHsjGL9fH5RSZCtRyYMJED****",
"expiration": "2025-11-11T08:01:03Z",
"securityToken": "CAISwwJ1q6Ft5B2yfSjI****"
},
"OIDCTokenInfo": {
"clientIds": "0oaxbqhfrfBl5lk2****",
"expirationTime": "2025-11-11T07:14:39Z",
"issuanceTime": "2025-11-11T06:14:39Z",
"issuer": "https://dev-xxxxxx.okta.com",
"subject": "00uxbq0z40UYy9bm****",
"verificationInfo": "Success"
},
"requestId": "5EB6E605-15EA-5D96-941D-2C62DC99****"
}其中Credentials中的資訊即為STS Token。
步驟六:使用STS Token訪問阿里雲資源
使用從步驟五擷取的STS Token訪問有許可權的阿里雲資源。