
# 认证鉴权
调用接口有如下两种认证方式，您可以选择其中一种进行认证鉴权。
- AK/SK认证：通过AK（Access Key ID）/SK（Secret Access Key)加密调用请求。
- Token认证：通过Token认证调用请求。
#### AK/SK认证
AK/SK认证就是使用AK/SK对请求进行签名，在请求时将签名信息添加到消息头，从而通过身份认证。
- AK（Access Key ID）：访问密钥ID。与私有访问密钥关联的唯一标识符；访问密钥ID和私有访问密钥一起使用，对请求进行加密签名。
- SK（Secret Access Key）：与访问密钥ID结合使用的密钥，对请求进行加密签名，可标识发送方，并防止请求被修改。
![](https://support.huaweicloud.com/api-drs/public_sys-resources/caution_3.0-zh-cn.png)
- AK/SK签名认证方式仅支持消息体大小12MB以内，12MB以上的请求请使用Token认证。
- API网关除了校验时间格式外，还会校验该时间值与网关收到请求的时间差，如果时间差大于15分钟，API网关将拒绝请求。因此客户端必须注意本地时间与时钟服务器的同步，避免请求消息头X-Sdk-Date的值出现较大误差。
 
以下结合一个[Demo](https://obs.cn-north-1.myhuaweicloud.com/apig-sdk/ApiGateway-java-sdk.zip)来介绍如何对一个请求进行签名，并通过HTTP Client发送一个HTTPS请求的过程。如果您不使用Demo工程，也可以直接下载API网关签名工具在其他工程中引用。
1. 生成AK/SK。如果已生成过AK/SK，则可跳过此步骤，找到原来已下载的AK/SK文件，文件名一般为：credentials.csv。
   
   1. 登录ManageOne运营面。
   
   2. 在页面右上角单击用户图标，在下拉列表中选择"个人设置"。
   
   3. 在"个人设置"页面选择"访问密钥"页签。
   
   4. 单击"创建"，新建AK/SK。
   
   5. 单击"确定"，AK/SK创建完成。
   
   6. 单击"立即下载"，下载访问密钥文件。
   
   7. 下载成功后，在credentials.csv文件中获取AK和SK信息。
      ![](https://support.huaweicloud.com/api-drs/public_sys-resources/caution_3.0-zh-cn.png)
      - 每个用户仅允许新增两个访问密钥。
      
      - 为保证访问密钥的安全，访问密钥仅在初次生成时自动下载，后续不可再次通过管理控制台界面获取。请在生成后妥善保管。
        
   
   
   
   
2. 获取示例代码，解压缩。
3. 打开IDEA，在菜单栏选择"File \> New \> Project from Existing Sources"。 
   选择解压后的"ApiGateway-java-sdk-*x.x.x*"文件夹，单击"OK"，导入示例工程。
   
   
4. 在"Import Project"页面，选择"Import project from external model"。 
   选择"Maven"，然后单击"Create"。
   ![](https://support.huaweicloud.com/api-drs/figure/zh-cn_image_0000002508930617.png "点击放大")
   
   
5. IDEA支持在当前窗口或新窗口创建工程。此处，在弹窗中单击"New Window"。
6. 修改HttpClientDemo.java中的API请求信息。 
   1. 本示例以AK和SK保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。以Linux系统为例在本地将[1]中获取的AK/SK设置为环境变量。
      1. 打开终端，执行以下命令打开环境变量配置文件。
         ```
         vi ~/.bashrc
         ```
         
      
      2. 在文件中添加如下环境变量配置，保存文件并退出编辑器。
         ```
         export HUAWEICLOUD_SDK_AK="已获取的AK值" 
         export HUAWEICLOUD_SDK_SK="已获取的SK值"
         ```
         
      
      3. 执行以下命令使配置文件生效。
         ```
         source ~/.bashrc
         ```
         
       
   
   2. 把API信息和已设置的环境变量替换到HttpClientDemo.java中的对应位置。
      如下示例所示，加粗部分信息需要替换成实际值。
      ```
      public class HttpClientDemo {
          private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientDemo.class);
          public static void main(String[] args) throws Exception {
              // Create a new request.
              Request httpClientRequest = new Request();
              try {
                  // Set the request parameters.
                  // AppKey, AppSecret, Method and Url are required parameters.
                  // Directly writing AK/SK in code is risky. For security, encrypt your AK/SK and store them in the configuration file or environment variables.
                  // In this example, the AK/SK are stored in environment variables for identity authentication. 
                  // Before running this example, set environment variables HUAWEICLOUD_SDK_AK and HUAWEICLOUD_SDK_SK.
                  httpClientRequest.setKey(System.getenv("HUAWEICLOUD_SDK_AK"));
                  httpClientRequest.setSecret(System.getenv("HUAWEICLOUD_SDK_SK"));
                  // Set a request method for http request.
                  httpClientRequest.setMethod("POST");
                  // Set a request URL in the format of https://{Endpoint}/{URI}.
                  httpClientRequest.setUrl("put your request url here");
                  httpClientRequest.addHeader("Content-Type", "text/plain");
                  // Set a body for http request.
                  httpClientRequest.setBody("put your request body here");
              } catch (Exception e) {
                  LOGGER.error(e.getMessage());
                  return;
              }
              CloseableHttpClient client = null;
              try {
                  // Sign the request.
                  HttpRequestBase signedRequest = Client.sign(httpClientRequest, Constant.SIGNATURE_ALGORITHM_SDK_HMAC_SHA256);
                  if (Constant.DO_VERIFY) {
                      // create httpClient and verify ssl certificate
                      HostName.setUrlHostName(httpClientRequest.getHost());
                      client = (CloseableHttpClient) SSLCipherSuiteUtil.createHttpClientWithVerify(Constant.INTERNATIONAL_PROTOCOL);
                  } else {
                      // create httpClient and do not verify ssl certificate
                      client = (CloseableHttpClient) SSLCipherSuiteUtil.createHttpClient(Constant.INTERNATIONAL_PROTOCOL);
                  }
                  HttpResponse response = client.execute(signedRequest);
                  // Print the body of the response.
                  HttpEntity resEntity = response.getEntity();
                  if (resEntity != null) {
                      String responseBody = EntityUtils.toString(resEntity, StandardCharsets.UTF_8);
                      LOGGER.info("HTTP response body: {}", responseBody);
                  }
              } catch (Exception e) {
                  LOGGER.error(e.getMessage());
              } finally {
                  if (client != null) {
                      client.close();
                  }
              }
          }
      }
      ```
      
   
   
   
   
7. 运行HttpClientDemo.java，对请求进行签名、访问API并打印结果。 
   如果改变AK或SK的值，API网关将返回错误信息error_msg。
   
   
 
#### Token认证
![](https://support.huaweicloud.com/api-drs/public_sys-resources/note_3.0-zh-cn.png)
Token的有效期为24小时，需要使用一个Token鉴权时，可以先缓存起来，避免频繁调用。
Token在计算机系统中代表令牌（临时）的意思，拥有Token就代表拥有某种权限。Token认证就是在调用API的时候将Token加到请求消息头，从而通过身份认证，获得操作API的权限。Token可通过调用[获取用户Token](https://support.huaweicloud.com/api-iam/iam_30_0001.html)接口获取。
云服务存在两种部署方式：项目级服务和全局级服务。
- 项目级服务需要获取项目级别的Token，此时请求body中auth.scope的取值为project。
- 全局级服务需要获取全局级别的Token，此时请求body中auth.scope的取值为domain。
调用本服务API需要项目级别的Token，即调用[获取用户Token](https://support.huaweicloud.com/api-iam/iam_30_0001.html)接口时，请求body中auth.scope的取值需要选择project，如下所示。
```
{ 
     "auth": { 
         "identity": { 
             "methods": [ 
                 "password" 
             ], 
             "password": { 
                 "user": { 
                     "name": "username", 
                     "password": "********", 
                     "domain": { 
                         "name": "domainname" 
                     } 
                 } 
             } 
         }, 
         "scope": { 
             "project": { 
                 "name": "projectname" 
             } 
         } 
     } 
 }
```
在[构造请求](https://support.huaweicloud.com/api-drs/drs_01_0008.html)中以调用获取用户Token的接口为例说明了如何调用API。获取Token后，再调用其他接口时，您需要在请求消息头中添加"X-Auth-Token"，其值即为Token。例如Token值为"ABCDEFJ...."，则调用接口时将"X-Auth-Token: ABCDEFJ...."加到请求消息头即可，如下所示。
```
POST https://iam.cn-north-1.myhuaweicloud.com/v3/auth/projects 
Content-Type: application/json 
X-Auth-Token: ABCDEFJ....
```
