# 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 | 文档首次发布 |