# huaweicloud-iam-authtokens-java **Repository Path**: HuaweiCloudDeveloper/huaweicloud-iam-authtokens-java ## Basic Information - **Project Name**: huaweicloud-iam-authtokens-java - **Description**: 获取IAM用户Token(使用密码+虚拟MFA)/获取IAM用户Token(使用密码)/获取委托Token/获取联邦认证scoped token - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master-dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2023-07-10 - **Last Updated**: 2025-06-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 1.功能介绍 Token是系统颁发给IAM用户的访问令牌,承载用户的身份、权限等信息。调用IAM以及其他云服务的接口时,可以使用本接口获取的IAM用户Token进行鉴权。 Token的scope可以分为domain级别和project级别。 该场景可以用于: * 获取IAM用户Token(通过用户名+密码的方式进行认证来获取IAM用户的Token)。 * 获取IAM用户Token(通过用户名+密码+虚拟MFA的方式进行认证。当IAM用户开启了的登录保护功能,并选择通过虚拟MFA验证时获取IAM用户的Token)。 * 获取委托Token(例如:A帐号希望B帐号管理自己的某些资源,所以A帐号创建了委托给B帐号,则A帐号为委托方,B帐号为被委托方。那么B帐号可以通过该接口获取委托token)。 * 获取联邦认证scoped token。 ## 2.前提条件 2.1获取AK/SK与其他参数 开发者在使用前需先获取账号的ak、sk、userName、userPwd、domainName、agencyName等字段。您需要拥有华为云账号以及对应的 Access Key(AK)和 Secret Access Key(SK)。请在华为云控制台“我的凭证-访问密钥”页面上创建和查看您的 AK/SK,更多信息请查看[访问密钥](https://support.huaweicloud.com/usermanual-ca/zh-cn_topic_0046606340.html)。 * 获取IAM用户Token(使用密码)需要的参数:userName:用户名。 userPwd:密码。 domainName:租户名。 * 获取IAM用户Token(使用密码+虚拟MFA)需要的参数:userName:用户名。 userPwd:密码。 domainName:租户名。 userId:已开启虚拟MFA方式的登录保护的IAM用户ID。 passcode:虚拟MFA验证码。 * 获取委托Token需要的参数:domainId:委托方A的账号ID。 domainName:委托方A的账号名称。 agencyName:委托方A创建的委托的名称。 * 获取联邦认证scoped token需要的参数:tokenId:联邦unscoped token的信息 * 一些公共参数:endpoint:终端节点,本示例中endpoint为"https://iam.myhuaweicloud.com"。 scopeDomainId:租户id。 scopeDomainName:租户名。 scopeProjectId:项目id。 scopeProjectName:项目名。 2.2SDK的获取和安装 您可以通过如下方式获取和安装 SDK:通过 Maven 安装项目依赖是使用 Java SDK 的推荐方法。 首先您需要在您的操作系统中下载并安装 Maven ,安装完成后您只需在 Java 项目的 pom.xml 文件加入相应的依赖项即可。本示例使用IAM SDK: com.huaweicloud.sdk huaweicloud-sdk-iam 3.1.28 2.3通用准备 2.3.1导入依赖模块部分示例 import com.huaweicloud.sdk.core.auth.GlobalCredentials; import com.huaweicloud.sdk.core.exception.ClientRequestException; import com.huaweicloud.sdk.core.http.HttpConfig; import com.huaweicloud.sdk.core.utils.StringUtils; 2.3.2配置客户端属性 HttpConfig config = HttpConfig.getDefaultHttpConfig(); config.withIgnoreSSLVerification(true); // 如果是本地IDEA调试,需要使用代理,代码如下: // config.setProxyHost(""); // config.setProxyPort(); // config.setProxyUsername(""); // config.setProxyPassword(""); 2.3.3创建认证 GlobalCredentials auth = new GlobalCredentials() .withAk(ak) .withSk(sk) .withDomainId(domainId); 2.3.4创建请求客户端 ArrayList endpoints = new ArrayList(); endpoints.add("https://iam.myhuaweicloud.com"); IamClient client = IamClient.newBuilder() .withCredential(auth) .withEndpoints(endpoints) .withHttpConfig(config).build(); ## 3.运行环境 Java JDK 1.8 及其以上版本。 ## 4.关键代码 public class CreateUserTokenSolution { private static final Logger logger = LoggerFactory.getLogger(CreateUserTokenSolution.class); public static void main(String[] args) { // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 String ak = System.getenv("HUAWEICLOUD_SDK_AK"); String sk = System.getenv("HUAWEICLOUD_SDK_SK"); String domainId = ""; // 租户id:domainId,必传 // 配置客户端属性 HttpConfig config = HttpConfig.getDefaultHttpConfig(); config.withIgnoreSSLVerification(true); // 创建认证 GlobalCredentials auth = new GlobalCredentials() .withAk(ak) .withSk(sk) .withDomainId(domainId); // 创建请求客户端 ArrayList endpoints = new ArrayList(); endpoints.add(""); // 固定值,填入:https://iam.myhuaweicloud.com IamClient client = IamClient.newBuilder() .withCredential(auth) .withEndpoints(endpoints) .withHttpConfig(config).build(); // 获取IAM用户Token(使用密码) createTokenByPassword(client); // 获取IAM用户Token(使用密码+虚拟MFA) createUserTokenByPasswordAndMfa(client); // 获取委托Token createAgencyToken(client); // 获取联邦认证scoped token createScopedToken(client); } private static void createTokenByPassword(IamClient client) { logger.info("####createTokenByPassword start!####"); String userName = ""; // 用户名,必传 String userPwd = System.getenv("HUAWEICLOUD_SDK_USER_PWD"); // 密码,必传,请先在本地环境中设置环境变量HUAWEICLOUD_SDK_USER_PWD String domainName = ""; // 租户名,必传 KeystoneCreateUserTokenByPasswordRequest request = new KeystoneCreateUserTokenByPasswordRequest(); KeystoneCreateUserTokenByPasswordRequestBody body = new KeystoneCreateUserTokenByPasswordRequestBody(); // 设置scope,如果需要设置scop,完成setScope()方法。 AuthScope authScope = setScope(); PwdPasswordUserDomain domainUser = new PwdPasswordUserDomain(); domainUser.withName(domainName); PwdPasswordUser userPassword = new PwdPasswordUser(); userPassword.withDomain(domainUser) .withName(userName) .withPassword(userPwd); PwdPassword passwordIdentity = new PwdPassword(); passwordIdentity.withUser(userPassword); List listIdentityMethods = new ArrayList(); listIdentityMethods.add(PwdIdentity.MethodsEnum.fromValue("password")); PwdIdentity identityAuth = new PwdIdentity(); identityAuth.withMethods(listIdentityMethods) .withPassword(passwordIdentity); PwdAuth authbody = new PwdAuth(); authbody.withIdentity(identityAuth) .withScope(authScope); body.withAuth(authbody); request.withBody(body); try { KeystoneCreateUserTokenByPasswordResponse response = client.keystoneCreateUserTokenByPassword(request); logger.info(response.toString()); } catch (ClientRequestException e) { LogError(e); } } private static void createUserTokenByPasswordAndMfa(IamClient client) { logger.info("####createUserTokenByPasswordAndMfa start!####"); String userName = ""; // 用户名,必传 String userPwd = System.getenv("HUAWEICLOUD_SDK_USER_PWD"); // 密码,必传,请先在本地环境中设置环境变量HUAWEICLOUD_SDK_USER_PWD String domainName = ""; // 租户名,必传 String userId = ""; // 已开启虚拟MFA方式的登录保护的IAM用户ID,必传 String passcode = ""; // 虚拟MFA验证码,必传 KeystoneCreateUserTokenByPasswordAndMfaRequest request = new KeystoneCreateUserTokenByPasswordAndMfaRequest(); KeystoneCreateUserTokenByPasswordAndMfaRequestBody body = new KeystoneCreateUserTokenByPasswordAndMfaRequestBody(); // 设置scope AuthScope authScope = setScope(); MfaTotpUser userTotp = new MfaTotpUser(); userTotp.withId(userId) .withPasscode(passcode); MfaTotp totpIdentity = new MfaTotp(); totpIdentity.withUser(userTotp); PwdPasswordUserDomain domainUser = new PwdPasswordUserDomain(); domainUser.withName(domainName); PwdPasswordUser userPassword = new PwdPasswordUser(); userPassword.withDomain(domainUser) .withName(userName) .withPassword(userPwd); PwdPassword passwordIdentity = new PwdPassword(); passwordIdentity.withUser(userPassword); List listIdentityMethods = new ArrayList(); listIdentityMethods.add(MfaIdentity.MethodsEnum.fromValue("password")); listIdentityMethods.add(MfaIdentity.MethodsEnum.fromValue(" totp")); MfaIdentity identityAuth = new MfaIdentity(); identityAuth.withMethods(listIdentityMethods) .withPassword(passwordIdentity) .withTotp(totpIdentity); MfaAuth authbody = new MfaAuth(); authbody.withIdentity(identityAuth) .withScope(authScope); body.withAuth(authbody); request.withBody(body); try { KeystoneCreateUserTokenByPasswordAndMfaResponse response = client.keystoneCreateUserTokenByPasswordAndMfa( request); logger.info(response.toString()); } catch (ClientRequestException e) { LogError(e); } } private static void createAgencyToken(IamClient client) { logger.info("####createAgencyToken start!####"); // domainId和domainName二选一 String domainId = ""; // 委托方A的账号ID,必传 String domainName = ""; // 委托方A的账号名称,必传 String agencyName = ""; // 委托方A创建的委托的名称,必传 KeystoneCreateAgencyTokenRequest request = new KeystoneCreateAgencyTokenRequest(); KeystoneCreateAgencyTokenRequestBody body = new KeystoneCreateAgencyTokenRequestBody(); // 设置scope,如果需要设置scop,完成setScopeForAgencyToken()方法。 AgencyTokenScope agencyTokenScope = setScopeForAgencyToken(); // 设置assume_role的具体信息 AgencyTokenAssumerole assumeRoleIdentity = new AgencyTokenAssumerole(); if (!StringUtils.isEmpty(domainId)) { assumeRoleIdentity.withDomainId(domainId).withAgencyName(agencyName); } else if (!StringUtils.isEmpty(domainName)) { assumeRoleIdentity.withDomainName(domainName).withAgencyName(agencyName); } else { logger.error("Need domainId or domainName!"); } List listIdentityMethods = new ArrayList(); listIdentityMethods.add(AgencyTokenIdentity.MethodsEnum.fromValue("assume_role")); AgencyTokenIdentity identityAuth = new AgencyTokenIdentity(); identityAuth.withMethods(listIdentityMethods) .withAssumeRole(assumeRoleIdentity); AgencyTokenAuth authbody = new AgencyTokenAuth(); authbody.withIdentity(identityAuth) .withScope(agencyTokenScope); body.withAuth(authbody); request.withBody(body); try { KeystoneCreateAgencyTokenResponse response = client.keystoneCreateAgencyToken(request); logger.info(response.toString()); } catch (ClientRequestException e) { LogError(e); } } private static void createScopedToken(IamClient client) { logger.info("####createScopedToken start!####"); String tokenId = ""; // 联邦unscoped token的信息,必传 KeystoneCreateScopedTokenRequest request = new KeystoneCreateScopedTokenRequest(); KeystoneCreateScopedTokenRequestBody body = new KeystoneCreateScopedTokenRequestBody(); // 设置scope,如果需要设置scop,完成setScopeForToken方法。 TokenSocpeOption tokenSocpeOption = setScopeForToken(); // 设置assume_role的具体信息 ScopedToken tokenIdentity = new ScopedToken(); tokenIdentity.withId(tokenId); List listIdentityMethods = new ArrayList(); listIdentityMethods.add("token"); ScopedTokenIdentity identityAuth = new ScopedTokenIdentity(); identityAuth.withMethods(listIdentityMethods) .withToken(tokenIdentity); ScopedTokenAuth authbody = new ScopedTokenAuth(); authbody.withIdentity(identityAuth) .withScope(tokenSocpeOption); body.withAuth(authbody); request.withBody(body); try { KeystoneCreateScopedTokenResponse response = client.keystoneCreateScopedToken(request); logger.info(response.toString()); } catch (ClientRequestException e) { LogError(e); } } private static AuthScope setScope() { // scope为domain级别时,scopeDomainId和scopeDomainName二选一 String scopeDomainId = ""; // 租户id String scopeDomainName = ""; // 租户名 // scope为project级别时,scopeProjectId和scopeProjectName二选一 String scopeProjectId = ""; // 项目id String scopeProjectName = ""; // 项目名 // 设置scope AuthScopeProject authScopeProject = new AuthScopeProject(); AuthScopeDomain authScopeDomain = new AuthScopeDomain(); AuthScope authScope = new AuthScope(); if (!StringUtils.isEmpty(scopeDomainId)) { authScopeDomain.withId(scopeDomainId); authScope.withDomain(authScopeDomain); } else if (!StringUtils.isEmpty(scopeDomainName)) { authScopeDomain.withName(scopeDomainName); authScope.withDomain(authScopeDomain); } else if (!StringUtils.isEmpty(scopeProjectId)) { authScopeProject.withId(scopeProjectId); authScope.withProject(authScopeProject); } else if (!StringUtils.isEmpty(scopeProjectName)) { authScopeProject.withName(scopeProjectName); authScope.withProject(authScopeProject); } return authScope; } private static AgencyTokenScope setScopeForAgencyToken() { // scope为domain级别时,scopeDomainId和scopeDomainName二选一 String scopeDomainId = ""; // 租户id String scopeDomainName = ""; // 租户名 // scope为project级别时,scopeProjectId和scopeProjectName二选一 String scopeProjectId = ""; // 项目id String scopeProjectName = ""; // 项目名 // 设置scope AgencyTokenScopeProject agencyTokenScopeProject = new AgencyTokenScopeProject(); AgencyTokenScopeDomain agencyTokenScopeDomain = new AgencyTokenScopeDomain(); AgencyTokenScope agencyTokenScope = new AgencyTokenScope(); if (!StringUtils.isEmpty(scopeDomainId)) { agencyTokenScopeDomain.withId(scopeDomainId); agencyTokenScope.withDomain(agencyTokenScopeDomain); } else if (!StringUtils.isEmpty(scopeDomainName)) { agencyTokenScopeDomain.withName(scopeDomainName); agencyTokenScope.withDomain(agencyTokenScopeDomain); } else if (!StringUtils.isEmpty(scopeProjectId)) { agencyTokenScopeProject.withId(scopeProjectId); agencyTokenScope.withProject(agencyTokenScopeProject); } else if (!StringUtils.isEmpty(scopeProjectName)) { agencyTokenScopeProject.withName(scopeProjectName); agencyTokenScope.withProject(agencyTokenScopeProject); } return agencyTokenScope; } private static TokenSocpeOption setScopeForToken() { // scope为domain级别时,scopeDomainId和scopeDomainName二选一 String scopeDomainId = ""; // 租户id String scopeDomainName = ""; // 租户名 // scope为project级别时,scopeProjectId和scopeProjectName二选一 String scopeProjectId = ""; // 项目id // 设置scope ScopeProjectOption scopeProjectOption = new ScopeProjectOption(); ScopeDomainOption scopeDomainOption = new ScopeDomainOption(); TokenSocpeOption tokenSocpeOption = new TokenSocpeOption(); if (!StringUtils.isEmpty(scopeDomainId)) { scopeDomainOption.withId(scopeDomainId); tokenSocpeOption.withDomain(scopeDomainOption); } else if (!StringUtils.isEmpty(scopeDomainName)) { scopeDomainOption.withName(scopeDomainName); tokenSocpeOption.withDomain(scopeDomainOption); } else if (!StringUtils.isEmpty(scopeProjectId)) { scopeProjectOption.withId(scopeProjectId); tokenSocpeOption.withProject(scopeProjectOption); } return tokenSocpeOption; } private static void LogError(ClientRequestException e) { logger.error("HttpStatusCode: " + e.getHttpStatusCode()); logger.error("RequestId: " + e.getRequestId()); logger.error("ErrorCode: " + e.getErrorCode()); logger.error("ErrorMsg: " + e.getErrorMsg()); } } ## 5.如何运行 该场景可以用于获取IAM用户Token(使用密码);获取IAM用户Token(使用密码+虚拟MFA);获取委托Token;获取联邦认证scoped token。 各个获取Token的方法可以独立执行,替换参数后,可以根据需要执行的方法注释掉其他方法,执行Run启动main方法即可。 ## 6.返回结果示例 6.1返回结果示例:获取IAM用户Token(使用密码) { token: class TokenResult { catalog: null domain: class TokenDomainResult { name: h********4 id: 09b9***************1200 } expiresAt: 2023-07-25T08:50:05.445000Z issuedAt: 2023-07-24T08:50:05.445000Z methods: [password] project: null roles: [class TokenRole { name: te_admin id: 0 }, class TokenRole { name: secu_admin id: 0 }, class TokenRole { name: te_agency id: 0 }] user: class TokenUserResult { name: l*****i id: 673c***************b05f passwordExpiresAt: domain: class TokenUserDomainResult { name: h********4 id: 09b9***************1200 } } } xSubjectToken: MIIU……………… } 6.2返回结果示例:获取IAM用户Token(使用密码+虚拟MFA) { token: class TokenResult { catalog: null domain: class TokenDomainResult { name: hid***********ou7 id: 2b29*******************964e } expiresAt: 2023-07-26T08:08:04.058000Z issuedAt: 2023-07-25T08:08:04.058000Z methods: [password, totp] project: null roles: [class TokenRole { name: op**************nce id: 0 }, class TokenRole { name: op*************inum id: 0 }] user: class TokenUserResult { name: lz******25 id: 0592**********************d651 passwordExpiresAt: domain: class TokenUserDomainResult { name: hid***********ou7 id: 2b29*******************964e } } } xSubjectToken: MIIVfwYJKoZIhv…… } 6.3返回结果示例:获取委托Token { token: class AgencyTokenResult { methods: [assume_role] expiresAt: 2023-07-26T08:11:09.698000Z issuedAt: 2023-07-25T08:11:09.698000Z assumedBy: class AgencyAssumedby { user: class AgencyAssumedbyUser { name: hid*********u7 id: 81b*********************151 domain: class AgencyAssumedbyUserDomain { name: hid***********hou7 id: 2b29*******************d964e } passwordExpiresAt: } } catalog: null domain: class AgencyTokenDomain { name: hid*********3hou7 id: 2b29*************************964e } project: null roles: [class TokenRole { name: secu_admin id: 0 }, class TokenRole { name: op_fine_grained id: 7 }] user: class AgencyTokenUser { name: hid******3hou7/hid******nn3hou7 id: 99b46**********************c1991c3 domain: class AgencyTokenUserDomain { id: 2b295********************2d964e name: hid*************n3hou7 } } } xSubjectToken: MIIWdQYJKoZIhvcNA…… } 6.4返回结果示例:获取联邦认证scoped token { token: class ScopeTokenResult { methods: [token] expiresAt: 2023-07-26T09:33:49.283000Z catalog: null domain: class TokenDomainResult { name: li*****n id: 3d63*****************802 } project: null roles: [class TokenRole { name: op_gated_ecs_spot_instance id: 0 }}] user: class ScopedTokenUser { domain: class TokenDomainResult { name: li*****n id: 3d6*****************802 } osFederation: class TokenUserOsfederation { groups: [] identityProvider: class OsfederationIdentityprovider { id: lzplzp } protocol: class OsfederationProtocol { id: saml } } id: yaoY************************PzMM name: Fed*************ser passwordExpiresAt: } issuedAt: 2023-07-25T09:33:49.283000Z } xSubjectToken: MIIVFgYJKoZIhvc... } ## 7.其他语言版本的说明 本代码参考华为云API Explorer的代码示例开发Java语言版本,对接SDK,如需使用其他版本,亦可参考华为云API Explorer提供的其他语言代码示例,链接如下: * [获取IAM用户Token(使用密码)](https://console.huaweicloud.com/apiexplorer/#/openapi/IAM/sdk?api=KeystoneCreateUserTokenByPassword) * [获取IAM用户Token(使用密码+虚拟MFA)](https://console.huaweicloud.com/apiexplorer/#/openapi/IAM/doc?api=KeystoneCreateUserTokenByPasswordAndMfa) * [获取委托Token](https://console.huaweicloud.com/apiexplorer/#/openapi/IAM/doc?api=KeystoneCreateAgencyToken) * [获取联邦认证scoped token](https://console.huaweicloud.com/apiexplorer/#/openapi/IAM/doc?api=KeystoneCreateScopedToken) ## 8.修订记录 | 发布日期 | 文档版本 | 修订说明 | |---------| ------------ | ------------ | | 2023-08 | 1.0 | 文档首次发布 |